65 files changed
+7499
-2698
No files matched your search
+10
-58
@@ -1,7 +1,6 @@
|
||||
|
||||
function newAnimation () {
|
||||
const MODULE_NAME = 'Animation'
|
||||
const INFO_LOG = false
|
||||
const ERROR_LOG = true
|
||||
const logger = newWebDebugLog()
|
||||
logger.fileName = MODULE_NAME
|
||||
@@ -29,75 +28,31 @@ function newAnimation () {
|
||||
return thisObject
|
||||
|
||||
function finalize () {
|
||||
try {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] finalize -> Entering function.') }
|
||||
|
||||
thisObject.stop()
|
||||
} catch (err) {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] finalize -> err = ' + err.stack) }
|
||||
}s
|
||||
thisObject.stop()
|
||||
}
|
||||
|
||||
function initialize (callBackFunction) {
|
||||
try {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] initialize -> Entering function.') }
|
||||
function initialize () {
|
||||
|
||||
/* Nothing to do here yet. */
|
||||
callBackFunction(GLOBAL.CUSTOM_OK_RESPONSE)
|
||||
} catch (err) {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> err = ' + err.stack) }
|
||||
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
|
||||
}
|
||||
}
|
||||
|
||||
function start (callBackFunction) {
|
||||
try {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] start -> Entering function.') }
|
||||
|
||||
animationLoop() // Inside this function the animation process is started, and at the same time it creates a loop.
|
||||
} catch (err) {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] start -> err = ' + err.stack) }
|
||||
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
|
||||
}
|
||||
function start () {
|
||||
animationLoop() // Inside this function the animation process is started, and at the same time it creates a loop.
|
||||
}
|
||||
|
||||
function stop (callBackFunction) {
|
||||
try {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] stop -> Entering function.') }
|
||||
|
||||
window.cancelAnimationFrame(animationLoopHandle)
|
||||
} catch (err) {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] stop -> err = ' + err.stack) }
|
||||
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
|
||||
}
|
||||
function stop () {
|
||||
window.cancelAnimationFrame(animationLoopHandle)
|
||||
}
|
||||
|
||||
function addCallBackFunction (key, callBack, callBackFunction) {
|
||||
try {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] addCallBackFunction -> Entering function.') }
|
||||
|
||||
callBackFunctions.set(key, callBack)
|
||||
} catch (err) {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] addCallBackFunction -> err = ' + err.stack) }
|
||||
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
|
||||
}
|
||||
function addCallBackFunction (key, callBack) {
|
||||
callBackFunctions.set(key, callBack)
|
||||
}
|
||||
|
||||
function removeCallBackFunction (key, callBackFunction) {
|
||||
try {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] removeCallBackFunction -> Entering function.') }
|
||||
|
||||
callBackFunctions.delete(key)
|
||||
} catch (err) {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] removeCallBackFunction -> err = ' + err.stack) }
|
||||
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
|
||||
}
|
||||
function removeCallBackFunction (key) {
|
||||
callBackFunctions.delete(key)
|
||||
}
|
||||
|
||||
function animationLoop () {
|
||||
try {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] animationLoop -> Entering function.') }
|
||||
|
||||
if (window.canvasApp.visible === true) {
|
||||
/* We set the canvas to its normal width and height */
|
||||
|
||||
@@ -131,8 +86,6 @@ function newAnimation () {
|
||||
}
|
||||
|
||||
function clearBrowserCanvas () {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] clearBrowserCanvas -> Entering function.') }
|
||||
|
||||
browserCanvasContext.beginPath()
|
||||
|
||||
browserCanvasContext.rect(0, 0, browserCanvas.width, browserCanvas.height)
|
||||
@@ -142,4 +95,3 @@ function newAnimation () {
|
||||
browserCanvasContext.fill()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
function newCandle () {
|
||||
let candle = {
|
||||
open: undefined,
|
||||
close: undefined,
|
||||
min: 10000000000000,
|
||||
max: 0,
|
||||
begin: undefined,
|
||||
end: undefined,
|
||||
direction: undefined,
|
||||
beginId: undefined,
|
||||
endId: undefined
|
||||
}
|
||||
|
||||
return candle
|
||||
}
|
||||
@@ -7,9 +7,7 @@ let splashScreenNeeded = true
|
||||
|
||||
function newCanvas () {
|
||||
const MODULE_NAME = 'Canvas'
|
||||
const INFO_LOG = false
|
||||
const ERROR_LOG = true
|
||||
const INTENSIVE_LOG = false
|
||||
const logger = newWebDebugLog()
|
||||
logger.fileName = MODULE_NAME
|
||||
|
||||
@@ -37,7 +35,9 @@ function newCanvas () {
|
||||
chartSpace: undefined,
|
||||
floatingSpace: undefined,
|
||||
panelsSpace: undefined,
|
||||
cockpitSpace: undefined,
|
||||
bottomSpace: undefined,
|
||||
strategySpace: undefined,
|
||||
animation: undefined,
|
||||
initialize: initialize,
|
||||
finalize: finalize
|
||||
@@ -46,44 +46,11 @@ function newCanvas () {
|
||||
thisObject.eventHandler = newEventHandler()
|
||||
|
||||
let splashScreen
|
||||
|
||||
let lastContainerMouseOver
|
||||
return thisObject
|
||||
|
||||
/*
|
||||
The canvas object represents a layer on top of the browser canvas object.
|
||||
|
||||
Graphically, thiscanvas object has 4 spaces:
|
||||
|
||||
1. The "Top Space": It is where Team and User information is displayed.
|
||||
2. The "Chart Space": It is where the charts are plotted.
|
||||
3. The "Floating Space": It is where floating elements live. There is a physics engine for this layer that allows these elements to flow.
|
||||
4. The "Panels Space": It is where panels live. --> This space has yet to be develop, currently pannels are somehow at the Chart Space.
|
||||
5. The "Bottom Space": Includes the breakpoint bar and a toolbar.
|
||||
|
||||
All these spaces are child objects of the Canvas object.
|
||||
|
||||
Canvas
|
||||
|
|
||||
|
|
||||
---> topSpace
|
||||
|
|
||||
|
|
||||
---> chartSpace
|
||||
|
|
||||
|
|
||||
---> flaotingSpace
|
||||
|
|
||||
|
|
||||
---> panelsSpace
|
||||
|
|
||||
|
|
||||
---> bottomSpace
|
||||
*/
|
||||
|
||||
function finalize () {
|
||||
try {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] finalize -> Entering function.') }
|
||||
|
||||
thisObject.chartSpace.finalize()
|
||||
thisObject.floatingSpace.finalize()
|
||||
|
||||
@@ -91,6 +58,7 @@ function newCanvas () {
|
||||
browserCanvas.removeEventListener('mouseup', onMouseUp, false)
|
||||
browserCanvas.removeEventListener('mousemove', onMouseMove, false)
|
||||
browserCanvas.removeEventListener('click', onMouseClick, false)
|
||||
browserCanvas.removeEventListener('mouseout', onMouseOut, false)
|
||||
|
||||
/* Mouse wheel events. */
|
||||
|
||||
@@ -107,10 +75,8 @@ function newCanvas () {
|
||||
}
|
||||
}
|
||||
|
||||
async function initialize (callBackFunction) {
|
||||
async function initialize () {
|
||||
try {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] initialize -> Entering function.') }
|
||||
|
||||
initializeBrowserCanvas()
|
||||
|
||||
addCanvasEvents()
|
||||
@@ -120,8 +86,11 @@ function newCanvas () {
|
||||
thisObject.topSpace = newTopSpace()
|
||||
await thisObject.topSpace.initialize()
|
||||
|
||||
thisObject.bottomSpace = newBottomSpace()
|
||||
thisObject.bottomSpace.initialize()
|
||||
thisObject.strategySpace = newStrategySpace()
|
||||
await thisObject.strategySpace.initialize()
|
||||
|
||||
thisObject.cockpitSpace = newCockpitSpace()
|
||||
thisObject.cockpitSpace.initialize()
|
||||
|
||||
thisObject.panelsSpace = newPanelsSpace()
|
||||
thisObject.panelsSpace.initialize()
|
||||
@@ -132,14 +101,13 @@ function newCanvas () {
|
||||
thisObject.chartSpace = newChartSpace()
|
||||
thisObject.chartSpace.initialize(onCharSpaceInitialized)
|
||||
|
||||
thisObject.bottomSpace = thisObject.cockpitSpace
|
||||
|
||||
function onCharSpaceInitialized (err) {
|
||||
try {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] initialize -> onCharSpaceInitialized -> Entering function.') }
|
||||
|
||||
viewPort.raiseEvents() // These events will impacts on objects just initialized.
|
||||
} catch (err) {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> onCharSpaceInitialized -> err = ' + err.stack) }
|
||||
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,87 +117,32 @@ function newCanvas () {
|
||||
splashScreen.initialize()
|
||||
|
||||
let animation = newAnimation()
|
||||
animation.initialize(onAnimationInitialized)
|
||||
animation.initialize()
|
||||
|
||||
function onAnimationInitialized (err) {
|
||||
try {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] initialize -> onAnimationInitialized -> Entering function.') }
|
||||
|
||||
thisObject.animation = animation
|
||||
thisObject.animation = animation
|
||||
|
||||
/* Here we add all the functions that will be called during the animation cycle. */
|
||||
|
||||
animation.addCallBackFunction('ViewPort Draw', viewPort.draw, onFunctionAdded)
|
||||
animation.addCallBackFunction('Chart Space Background', thisObject.chartSpace.drawBackground, onFunctionAdded)
|
||||
animation.addCallBackFunction('Chart Space', thisObject.chartSpace.draw, onFunctionAdded)
|
||||
animation.addCallBackFunction('Floating Space', thisObject.floatingSpace.floatingLayer.physicsLoop, onFunctionAdded)
|
||||
animation.addCallBackFunction('Panels Space', thisObject.panelsSpace.draw, onFunctionAdded)
|
||||
animation.addCallBackFunction('Splash Screen', splashScreen.draw, onFunctionAdded)
|
||||
animation.addCallBackFunction('ViewPort Animate', viewPort.animate, onFunctionAdded)
|
||||
animation.addCallBackFunction('Bottom Space', thisObject.bottomSpace.draw, onFunctionAdded)
|
||||
animation.addCallBackFunction('Top Space', thisObject.topSpace.draw, onFunctionAdded)
|
||||
animation.start(onStart)
|
||||
|
||||
function onFunctionAdded (err) {
|
||||
try {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] initialize -> onAnimationInitialized -> onFunctionAdded -> Entering function.') }
|
||||
|
||||
if (err.result === GLOBAL.DEFAULT_FAIL_RESPONSE.result) {
|
||||
animation.stop()
|
||||
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> onAnimationInitialized -> onFunctionAdded -> Animation Stopped since a vital funtion could not be added.') }
|
||||
|
||||
/* Display some Error Page here. */
|
||||
}
|
||||
} catch (err) {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> onAnimationInitialized -> onFunctionAdded -> err = ' + err.stack) }
|
||||
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
|
||||
}
|
||||
}
|
||||
|
||||
function onStart (err) {
|
||||
try {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] initialize -> onAnimationInitialized -> onStart -> Entering function.') }
|
||||
|
||||
switch (err.result) {
|
||||
case GLOBAL.DEFAULT_OK_RESPONSE.result: {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] initialize -> onAnimationInitialized -> onStart -> Received OK Response.') }
|
||||
callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE)
|
||||
return
|
||||
}
|
||||
|
||||
case GLOBAL.DEFAULT_FAIL_RESPONSE.result: {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] initialize -> onAnimationInitialized -> onStart -> Received FAIL Response.') }
|
||||
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
|
||||
return
|
||||
}
|
||||
|
||||
default: {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] initialize -> onAnimationInitialized -> onStart -> Received Unexpected Response.') }
|
||||
callBackFunction(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> onAnimationInitialized -> onStart -> err = ' + err.stack) }
|
||||
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> onAnimationInitialized -> err = ' + err.stack) }
|
||||
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
|
||||
}
|
||||
}
|
||||
animation.addCallBackFunction('Floating Space Draw', thisObject.floatingSpace.draw)
|
||||
animation.addCallBackFunction('Floating Space Physics', thisObject.floatingSpace.physics)
|
||||
animation.addCallBackFunction('Chart Space Background', thisObject.chartSpace.drawBackground)
|
||||
animation.addCallBackFunction('Chart Space Draw', thisObject.chartSpace.draw)
|
||||
animation.addCallBackFunction('Chart Space Physics', thisObject.chartSpace.physics)
|
||||
animation.addCallBackFunction('Panels Space', thisObject.panelsSpace.draw)
|
||||
animation.addCallBackFunction('ViewPort Animate', viewPort.animate)
|
||||
animation.addCallBackFunction('CockpitSpace Draw', thisObject.cockpitSpace.draw)
|
||||
animation.addCallBackFunction('CockpitSpace Physics', thisObject.cockpitSpace.physics)
|
||||
animation.addCallBackFunction('Top Space Draw', thisObject.topSpace.draw)
|
||||
animation.addCallBackFunction('Strategy Space Draw', thisObject.strategySpace.draw)
|
||||
animation.addCallBackFunction('Splash Screen Draw', splashScreen.draw)
|
||||
animation.start()
|
||||
} catch (err) {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> err = ' + err.stack) }
|
||||
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
|
||||
}
|
||||
}
|
||||
|
||||
function initializeBrowserCanvas () {
|
||||
try {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] initializeBrowserCanvas -> Entering function.') }
|
||||
|
||||
browserCanvasContext = browserCanvas.getContext('2d')
|
||||
// browserCanvasContext.font = 'italic small-caps bold 12px Saira'
|
||||
browserCanvasContext.font = 'Saira'
|
||||
@@ -242,14 +155,13 @@ function newCanvas () {
|
||||
|
||||
function addCanvasEvents () {
|
||||
try {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] addCanvasEvents -> Entering function.') }
|
||||
|
||||
/* Mouse down and up events to control the drag of the canvas. */
|
||||
|
||||
browserCanvas.addEventListener('mousedown', onMouseDown, false)
|
||||
browserCanvas.addEventListener('mouseup', onMouseUp, false)
|
||||
browserCanvas.addEventListener('mousemove', onMouseMove, false)
|
||||
browserCanvas.addEventListener('click', onMouseClick, false)
|
||||
browserCanvas.addEventListener('mouseout', onMouseOut, false)
|
||||
|
||||
/* Mouse wheel events. */
|
||||
|
||||
@@ -273,21 +185,6 @@ function newCanvas () {
|
||||
|
||||
function onMouseDown (event) {
|
||||
try {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] onMouseDown -> Entering function.') }
|
||||
|
||||
/*
|
||||
|
||||
There are four types of elements that can be dragged.
|
||||
|
||||
1. Panels.
|
||||
2. Floating Elements (Currently only FloatingObjects).
|
||||
3. Charts.
|
||||
4. The Viewport.
|
||||
|
||||
We eveluate each space in order to see if they are holding the element being dragged, and we fallout at the Viewport.
|
||||
|
||||
*/
|
||||
|
||||
let point = {
|
||||
x: event.pageX,
|
||||
y: event.pageY - window.canvasApp.topMargin
|
||||
@@ -298,6 +195,20 @@ function newCanvas () {
|
||||
|
||||
let container
|
||||
|
||||
/* We check if the mouse is over an element of the Strategy Space / */
|
||||
|
||||
container = thisObject.strategySpace.getContainer(point)
|
||||
|
||||
if (container !== undefined && container.isDraggeable === true) {
|
||||
containerBeingDragged = container
|
||||
containerDragStarted = true
|
||||
return
|
||||
}
|
||||
|
||||
if (container !== undefined && container.isDraggeable === false) {
|
||||
return
|
||||
}
|
||||
|
||||
/* We check if the mouse is over an element of the Top Space / */
|
||||
|
||||
container = thisObject.topSpace.getContainer(point)
|
||||
@@ -308,9 +219,9 @@ function newCanvas () {
|
||||
return
|
||||
}
|
||||
|
||||
/* We check if the mouse is over an element of the Bottom Space / */
|
||||
/* We check if the mouse is over an element of the CockpitSpace / */
|
||||
|
||||
container = thisObject.bottomSpace.getContainer(point)
|
||||
container = thisObject.cockpitSpace.getContainer(point)
|
||||
|
||||
if (container !== undefined && container.isDraggeable === true) {
|
||||
containerBeingDragged = container
|
||||
@@ -333,26 +244,34 @@ function newCanvas () {
|
||||
return
|
||||
}
|
||||
|
||||
/* We check if the mouse is over a floatingObject/ */
|
||||
|
||||
floatingObjectBeingDragged = thisObject.floatingSpace.floatingLayer.isInside(point.x, point.y)
|
||||
|
||||
if (floatingObjectBeingDragged >= 0) {
|
||||
floatingObjectDragStarted = true
|
||||
return
|
||||
}
|
||||
|
||||
/* If it is not, then we check if it is over any of the existing containers at the Chart Space. */
|
||||
/* we check if it is over any of the existing containers at the Chart Space. */
|
||||
|
||||
container = thisObject.chartSpace.getContainer(point)
|
||||
|
||||
if (container !== undefined) {
|
||||
if (container.isDraggeable === true) {
|
||||
containerBeingDragged = container
|
||||
containerDragStarted = true
|
||||
return
|
||||
} else {
|
||||
viewPortBeingDragged = true
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
container = thisObject.floatingSpace.getContainer(point)
|
||||
|
||||
if (container !== undefined && container.isDraggeable === true) {
|
||||
containerBeingDragged = container
|
||||
containerDragStarted = true
|
||||
floatingObjectDragStarted = true
|
||||
return
|
||||
}
|
||||
|
||||
viewPortBeingDragged = true
|
||||
if (container !== undefined && container.isClickeable === true) {
|
||||
/* We dont want to mess up with the click */
|
||||
return
|
||||
}
|
||||
} catch (err) {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] onMouseDown -> err = ' + err.stack) }
|
||||
}
|
||||
@@ -360,8 +279,6 @@ function newCanvas () {
|
||||
|
||||
function onMouseClick (event) {
|
||||
try {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] onMouseClick -> Entering function.') }
|
||||
|
||||
if (ignoreNextClick === true) {
|
||||
ignoreNextClick = false
|
||||
return
|
||||
@@ -373,6 +290,15 @@ function newCanvas () {
|
||||
|
||||
let container
|
||||
|
||||
/* We check if the mouse is over an element of the Strategy Space / */
|
||||
|
||||
container = thisObject.strategySpace.getContainer(point)
|
||||
|
||||
if (container !== undefined && container.isClickeable === true) {
|
||||
container.eventHandler.raiseEvent('onMouseClick', point)
|
||||
return
|
||||
}
|
||||
|
||||
/* We check if the mouse is over an element of the Top Space / */
|
||||
|
||||
container = thisObject.topSpace.getContainer(point)
|
||||
@@ -382,9 +308,9 @@ function newCanvas () {
|
||||
return
|
||||
}
|
||||
|
||||
/* We check if the mouse is over an element of the Bottom Space / */
|
||||
/* We check if the mouse is over an element of the CockpitSpace / */
|
||||
|
||||
container = thisObject.bottomSpace.getContainer(point)
|
||||
container = thisObject.cockpitSpace.getContainer(point)
|
||||
|
||||
if (container !== undefined && container.isClickeable === true) {
|
||||
container.eventHandler.raiseEvent('onMouseClick', point)
|
||||
@@ -397,17 +323,6 @@ function newCanvas () {
|
||||
|
||||
if (container !== undefined && container.isClickeable === true) {
|
||||
container.eventHandler.raiseEvent('onMouseClick', point)
|
||||
return
|
||||
}
|
||||
|
||||
/* We check if the mouse is over a floatingObject/ */
|
||||
|
||||
let floatingObjectBeingClicked = thisObject.floatingSpace.floatingLayer.isInside(point.x, point.y)
|
||||
|
||||
if (floatingObjectBeingClicked >= 0) {
|
||||
let floatingObject = thisObject.floatingSpace.floatingLayer.getFloatingObject(undefined, floatingObjectBeingClicked)
|
||||
floatingObject.eventHandler.raiseEvent('onMouseClick', point)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -419,15 +334,36 @@ function newCanvas () {
|
||||
container.eventHandler.raiseEvent('onMouseClick', point)
|
||||
return
|
||||
}
|
||||
|
||||
/* We check if the mouse is over a floatingObject/ */
|
||||
container = thisObject.floatingSpace.getContainer(point)
|
||||
|
||||
if (container !== undefined && container.isClickeable === true) {
|
||||
container.eventHandler.raiseEvent('onMouseClick', point)
|
||||
return
|
||||
}
|
||||
} catch (err) {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] onMouseClick -> err = ' + err.stack) }
|
||||
}
|
||||
}
|
||||
|
||||
function onMouseUp (event) {
|
||||
try {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] onMouseUp -> Entering function.') }
|
||||
function onMouseOut (event) {
|
||||
deactivateDragging(event)
|
||||
|
||||
/* When the mouse leaves the canvas, our elements needs to react to the fact that the mouse is over a far away place */
|
||||
let thisEvent = {
|
||||
pageX: VERY_LARGE_NUMBER,
|
||||
pageY: VERY_LARGE_NUMBER
|
||||
}
|
||||
onMouseOver(thisEvent)
|
||||
}
|
||||
|
||||
function onMouseUp (event) {
|
||||
deactivateDragging(event)
|
||||
}
|
||||
|
||||
function deactivateDragging (event) {
|
||||
try {
|
||||
if (containerDragStarted || viewPortBeingDragged || floatingObjectDragStarted) {
|
||||
thisObject.eventHandler.raiseEvent('Drag Finished', undefined)
|
||||
}
|
||||
@@ -455,8 +391,6 @@ function newCanvas () {
|
||||
|
||||
function onMouseMove (event) {
|
||||
try {
|
||||
if (INTENSIVE_LOG === true) { logger.write('[INFO] onMouseMove -> Entering function.') }
|
||||
|
||||
let point = {
|
||||
x: event.pageX,
|
||||
y: event.pageY - window.canvasApp.topMargin
|
||||
@@ -467,12 +401,22 @@ function newCanvas () {
|
||||
|
||||
if (containerDragStarted === true || floatingObjectDragStarted === true || viewPortBeingDragged === true) {
|
||||
if (floatingObjectDragStarted === true) {
|
||||
if (thisObject.floatingSpace.floatingLayer.isInsideFloatingObject(floatingObjectBeingDragged, point.x, point.y) === false) {
|
||||
/* This means that the user stop moving the mouse and the floatingObject floatingObject out of the pointer.
|
||||
In this case we cancell the drag operation . */
|
||||
|
||||
let targetContainer = thisObject.floatingSpace.getContainer(point)
|
||||
if (targetContainer !== undefined) {
|
||||
if (targetContainer.id !== containerBeingDragged.id) {
|
||||
containerBeingDragged = undefined
|
||||
containerDragStarted = false
|
||||
floatingObjectDragStarted = false
|
||||
browserCanvas.style.cursor = 'auto'
|
||||
ignoreNextClick = true
|
||||
return
|
||||
}
|
||||
} else {
|
||||
containerDragStarted = false
|
||||
containerBeingDragged = undefined
|
||||
floatingObjectDragStarted = false
|
||||
browserCanvas.style.cursor = 'auto'
|
||||
ignoreNextClick = true
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -491,12 +435,6 @@ function newCanvas () {
|
||||
|
||||
function onMouseOver (event) {
|
||||
try {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] onMouseOver -> Entering function.') }
|
||||
|
||||
/* First we raise the event signaling theat the mouse is potentially over another item, so that the current item can turn itself off. */
|
||||
|
||||
thisObject.eventHandler.raiseEvent('onMouseNotOver')
|
||||
|
||||
/* Then we check who is the current object underneeth the mounse. */
|
||||
|
||||
let point = {
|
||||
@@ -506,51 +444,80 @@ function newCanvas () {
|
||||
|
||||
let container
|
||||
|
||||
/* We check if the mouse is over an element of the Top Space / */
|
||||
/* We check if the mouse is over an element of the Strategy Space / */
|
||||
|
||||
container = thisObject.topSpace.getContainer(point)
|
||||
if (thisObject.strategySpace !== undefined) {
|
||||
container = thisObject.strategySpace.getContainer(point)
|
||||
|
||||
if (container !== undefined && container.detectMouseOver === true) {
|
||||
container.eventHandler.raiseEvent('onMouseOver', point)
|
||||
return
|
||||
if (container !== undefined && container.detectMouseOver === true) {
|
||||
containerFound()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
/* We check if the mouse is over an element of the Bottom Space / */
|
||||
/* We check if the mouse is over an element of the Top Space / */
|
||||
|
||||
container = thisObject.bottomSpace.getContainer(point)
|
||||
if (thisObject.topSpace !== undefined) {
|
||||
container = thisObject.topSpace.getContainer(point)
|
||||
|
||||
if (container !== undefined && container.detectMouseOver === true) {
|
||||
container.eventHandler.raiseEvent('onMouseOver', point)
|
||||
return
|
||||
if (container !== undefined && container.detectMouseOver === true) {
|
||||
containerFound()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
/* We check if the mouse is over an element of the CockpitSpace / */
|
||||
|
||||
if (thisObject.cockpitSpace !== undefined) {
|
||||
container = thisObject.cockpitSpace.getContainer(point)
|
||||
|
||||
if (container !== undefined && container.detectMouseOver === true) {
|
||||
containerFound()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
/* We check if the mouse is over a panel/ */
|
||||
|
||||
container = thisObject.panelsSpace.getContainer(point)
|
||||
if (thisObject.panelsSpace !== undefined) {
|
||||
container = thisObject.panelsSpace.getContainer(point)
|
||||
|
||||
if (container !== undefined && container.detectMouseOver === true) {
|
||||
container.eventHandler.raiseEvent('onMouseOver', point)
|
||||
return
|
||||
}
|
||||
|
||||
/* We check if the mouse is over a floatingObject/ */
|
||||
|
||||
let floatingObjectBeingClicked = thisObject.floatingSpace.floatingLayer.isInside(point.x, point.y)
|
||||
|
||||
if (floatingObjectBeingClicked >= 0) {
|
||||
let floatingObject = thisObject.floatingSpace.floatingLayer.getFloatingObject(undefined, floatingObjectBeingClicked)
|
||||
floatingObject.eventHandler.raiseEvent('onMouseOver', point)
|
||||
|
||||
return
|
||||
if (container !== undefined && container.detectMouseOver === true) {
|
||||
containerFound()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
/* If it is not, then we check if it is over any of the existing containers at the Chart Space. */
|
||||
|
||||
container = thisObject.chartSpace.getContainer(point, GET_CONTAINER_PURPOSE.MOUSE_OVER)
|
||||
if (thisObject.chartSpace !== undefined) {
|
||||
container = thisObject.chartSpace.getContainer(point, GET_CONTAINER_PURPOSE.MOUSE_OVER)
|
||||
|
||||
if (container !== undefined && container.detectMouseOver === true) {
|
||||
containerFound()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
/* We check if the mouse is over a floatingObject/ */
|
||||
if (thisObject.floatingSpace !== undefined) {
|
||||
container = thisObject.floatingSpace.getContainer(point)
|
||||
|
||||
if (container !== undefined && container.detectMouseOver === true) {
|
||||
containerFound()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
function containerFound () {
|
||||
if (lastContainerMouseOver !== undefined) {
|
||||
if (container.id !== lastContainerMouseOver.id) {
|
||||
lastContainerMouseOver.eventHandler.raiseEvent('onMouseNotOver', point)
|
||||
}
|
||||
}
|
||||
|
||||
if (container !== undefined && container.detectMouseOver === true) {
|
||||
container.eventHandler.raiseEvent('onMouseOver', point)
|
||||
return
|
||||
lastContainerMouseOver = container
|
||||
}
|
||||
} catch (err) {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] onMouseOver -> err = ' + err.stack) }
|
||||
@@ -559,8 +526,6 @@ function newCanvas () {
|
||||
|
||||
function onMouseWheel (event) {
|
||||
try {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] onMouseWheel -> Entering function.') }
|
||||
|
||||
// cross-browser wheel delta
|
||||
var event = window.event || event // old IE support
|
||||
let delta = Math.max(-1, Math.min(1, event.wheelDelta || -event.detail))
|
||||
@@ -573,45 +538,46 @@ function newCanvas () {
|
||||
}
|
||||
|
||||
event.mousePosition = point
|
||||
let container
|
||||
container = canvas.panelsSpace.getContainer({ x: point.x, y: point.y })
|
||||
|
||||
let panelContainer = canvas.panelsSpace.getContainer({ x: point.x, y: point.y })
|
||||
|
||||
if (panelContainer !== undefined && panelContainer.isWheelable === true) {
|
||||
panelContainer.eventHandler.raiseEvent('Mouse Wheel', event)
|
||||
if (container !== undefined && container.isWheelable === true) {
|
||||
container.eventHandler.raiseEvent('onMouseWheel', event)
|
||||
return false // This instructs the browser not to take the event and scroll the page.
|
||||
}
|
||||
|
||||
/* We try second with floating objects. */
|
||||
/* We try the CockpitSpace. */
|
||||
|
||||
let floatingObjectIndex = canvas.floatingSpace.floatingLayer.isInside(point.x, point.y)
|
||||
container = canvas.cockpitSpace.getContainer({ x: point.x, y: point.y })
|
||||
|
||||
if (floatingObjectIndex > 0) {
|
||||
canvas.floatingSpace.floatingLayer.changeTargetRepulsion(event.wheelDelta)
|
||||
if (container !== undefined && container.isWheelable === true) {
|
||||
container.eventHandler.raiseEvent('onMouseWheel', event)
|
||||
return false // This instructs the browser not to take the event and scroll the page.
|
||||
}
|
||||
|
||||
/* We try the Bottom Space. */
|
||||
/* Chart Space. */
|
||||
|
||||
let bottomContainer = canvas.bottomSpace.getContainer({ x: point.x, y: point.y })
|
||||
|
||||
if (bottomContainer !== undefined && bottomContainer.isWheelable === true) {
|
||||
bottomContainer.eventHandler.raiseEvent('Mouse Wheel', event)
|
||||
container = canvas.chartSpace.getContainer({ x: point.x, y: point.y }, GET_CONTAINER_PURPOSE.MOUSE_WHEEL)
|
||||
if (container !== undefined && container.isWheelable === true) {
|
||||
container.eventHandler.raiseEvent('onMouseWheel', event)
|
||||
return false // This instructs the browser not to take the event and scroll the page.
|
||||
}
|
||||
|
||||
/* Finally we try the Chart Space. */
|
||||
|
||||
let chartContainer = canvas.chartSpace.getContainer({ x: point.x, y: point.y }, GET_CONTAINER_PURPOSE.MOUSE_WHEEL)
|
||||
|
||||
if (chartContainer !== undefined && chartContainer.isWheelable === true) {
|
||||
chartContainer.eventHandler.raiseEvent('Mouse Wheel', event)
|
||||
return false // This instructs the browser not to take the event and scroll the page.
|
||||
} else {
|
||||
/* If all the above fails, we fallback into applying zoom to the viewPort */
|
||||
|
||||
if (container !== undefined) {
|
||||
viewPort.applyZoom(delta)
|
||||
return false
|
||||
}
|
||||
|
||||
/* We try second with floating objects. */
|
||||
|
||||
container = canvas.floatingSpace.getContainer({ x: point.x, y: point.y })
|
||||
|
||||
if (container !== undefined && container.isWheelable === true) {
|
||||
container.eventHandler.raiseEvent('onMouseWheel', event)
|
||||
return false // This instructs the browser not to take the event and scroll the page.
|
||||
}
|
||||
|
||||
return false
|
||||
} catch (err) {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] onMouseWheel -> err = ' + err.stack) }
|
||||
}
|
||||
@@ -619,8 +585,6 @@ function newCanvas () {
|
||||
|
||||
function checkDrag (event) {
|
||||
try {
|
||||
if (INTENSIVE_LOG === true) { logger.write('[INFO] checkDrag -> Entering function.') }
|
||||
|
||||
if (containerDragStarted === true || floatingObjectDragStarted === true || viewPortBeingDragged === true) {
|
||||
let point = {
|
||||
x: event.pageX,
|
||||
@@ -630,15 +594,6 @@ function newCanvas () {
|
||||
browserCanvas.style.cursor = 'grabbing'
|
||||
thisObject.eventHandler.raiseEvent('Dragging', undefined)
|
||||
|
||||
let targetFloatingObject = thisObject.floatingSpace.floatingLayer.isInside(point.x, point.y)
|
||||
|
||||
if (floatingObjectDragStarted) {
|
||||
let floatingObject = thisObject.floatingSpace.floatingLayer.getFloatingObject(undefined, floatingObjectBeingDragged)
|
||||
|
||||
floatingObject.currentPosition.x = dragVector.upX
|
||||
floatingObject.currentPosition.y = dragVector.upY
|
||||
}
|
||||
|
||||
if (containerDragStarted || viewPortBeingDragged) {
|
||||
/* The parameters received have been captured with zoom applied. We must remove the zoom in order to correctly modify the displacement. */
|
||||
|
||||
@@ -669,8 +624,10 @@ function newCanvas () {
|
||||
}
|
||||
|
||||
if (containerBeingDragged !== undefined) {
|
||||
containerBeingDragged.frame.position.x = containerBeingDragged.frame.position.x + displaceVector.x
|
||||
containerBeingDragged.frame.position.y = containerBeingDragged.frame.position.y + displaceVector.y
|
||||
let moveSucceed = containerBeingDragged.displace(displaceVector)
|
||||
if (moveSucceed === false) {
|
||||
deactivateDragging(event)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
File renamed without changes.
@@ -221,7 +221,7 @@ function newPlottersManager () {
|
||||
|
||||
let plotter = getNewPlotter(competition.plotter.host, competition.plotter.codeName, competition.plotter.moduleName)
|
||||
|
||||
plotter.container.connectToParent(thisObject.container, true, true)
|
||||
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
|
||||
@@ -285,7 +285,7 @@ function newPlottersManager () {
|
||||
|
||||
botAvatar.src = window.canvasApp.context.fbProfileImages.get(TEAM + '-' + BOT)
|
||||
|
||||
competitionPlotter.plotter.payload[k].profile.downLabel = bot.displayName
|
||||
competitionPlotter.plotter.payload[k].profile.title = bot.displayName
|
||||
competitionPlotter.plotter.payload[k].profile.imageId = imageId
|
||||
competitionPlotter.plotter.payload[k].profile.botAvatar = botAvatar
|
||||
|
||||
@@ -463,7 +463,7 @@ function newPlottersManager () {
|
||||
|
||||
let plotter = getNewPlotter(pProductCard.product.plotter.devTeam, pProductCard.product.plotter.codeName, pProductCard.product.plotter.moduleName)
|
||||
|
||||
plotter.container.connectToParent(thisObject.container, true, true)
|
||||
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
|
||||
@@ -525,8 +525,8 @@ function newPlottersManager () {
|
||||
if (productPlotter.plotter.payload !== undefined) {
|
||||
let imageId = pProductCard.bot.devTeam + '.' + pProductCard.bot.profilePicture
|
||||
|
||||
productPlotter.plotter.payload.profile.upLabel = pProductCard.product.shortDisplayName
|
||||
productPlotter.plotter.payload.profile.downLabel = pProductCard.bot.displayName
|
||||
productPlotter.plotter.payload.profile.subTitle = pProductCard.product.shortDisplayName
|
||||
productPlotter.plotter.payload.profile.title = pProductCard.bot.displayName
|
||||
productPlotter.plotter.payload.profile.imageId = imageId
|
||||
productPlotter.plotter.payload.profile.botAvatar = pProductCard.bot.avatar
|
||||
|
||||
File renamed without changes.
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
|
||||
Markets are a function of time. When watching them, end users must be positioned at one particular point in time. The system currently allows users
|
||||
to position themselves at any time they like.
|
||||
@@ -11,15 +11,17 @@ each one with it own charts, and each one positioned at an especific point in ti
|
||||
|
||||
function newTimeMachine () {
|
||||
const MODULE_NAME = 'Time Machine'
|
||||
const INFO_LOG = false
|
||||
const logger = newWebDebugLog()
|
||||
logger.fileName = MODULE_NAME
|
||||
|
||||
let thisObject = {
|
||||
container: undefined,
|
||||
timeScale: undefined,
|
||||
rateScale: undefined,
|
||||
charts: [],
|
||||
physics: physics,
|
||||
drawBackground: drawBackground,
|
||||
draw: draw,
|
||||
charts: [],
|
||||
getContainer: getContainer, // returns the inner most container that holds the point received by parameter.
|
||||
initialize: initialize,
|
||||
finalize: finalize
|
||||
@@ -37,33 +39,36 @@ function newTimeMachine () {
|
||||
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.
|
||||
// ... also to request a reference to the object for the cases we need it.
|
||||
const SEPARATION_BETWEEN_TIMELINE_CHARTS = 1.5
|
||||
|
||||
let timeScale
|
||||
let rigthScale
|
||||
|
||||
let timeLineCoordinateSystem = newTimeLineCoordinateSystem()
|
||||
|
||||
let mouse = {
|
||||
position: {
|
||||
x: 0,
|
||||
y: 0
|
||||
}
|
||||
}
|
||||
|
||||
return thisObject
|
||||
|
||||
function finalize () {
|
||||
try {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] finalize -> Entering function.') }
|
||||
|
||||
for (let i = 0; i < thisObject.charts.length; i++) {
|
||||
let chart = thisObject.charts[i]
|
||||
chart.finalize()
|
||||
}
|
||||
} catch (err) {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] finalize -> err = ' + err.stack) }
|
||||
for (let i = 0; i < thisObject.charts.length; i++) {
|
||||
let chart = thisObject.charts[i]
|
||||
chart.finalize()
|
||||
}
|
||||
|
||||
thisObject.container.finalize()
|
||||
thisObject.container = undefined
|
||||
thisObject.timeScale.finalize()
|
||||
thisObject.timeScale = undefined
|
||||
thisObject.rateScale.finalize()
|
||||
thisObject.rateScale = undefined
|
||||
}
|
||||
|
||||
function initialize (callBackFunction) {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] initialize -> Entering function.') }
|
||||
|
||||
/* Each Time Machine has a Control Panel. */
|
||||
/* Each Time Machine has a Control Panel. */
|
||||
|
||||
let panelOwner = 'Global'
|
||||
controlPanelHandle = canvas.panelsSpace.createNewPanel('Time Control Panel', undefined, panelOwner)
|
||||
@@ -71,18 +76,13 @@ function newTimeMachine () {
|
||||
|
||||
recalculateScale()
|
||||
|
||||
thisObject.container.eventHandler.listenToEvent('Dimmensions Changed', function (event) {
|
||||
recalculateScale()
|
||||
moveToUserPosition(thisObject.container, timeLineCoordinateSystem, false, false, event.mousePosition)
|
||||
})
|
||||
|
||||
/* First, we initialize the market that we are going to show first on screen. Later all the other markets will be initialized on the background. */
|
||||
/* First, we initialize the market that we are going to show first on screen. Later all the other markets will be initialized on the background. */
|
||||
|
||||
let position = 0 // This defines the position of each chart respect to each other.
|
||||
|
||||
let timelineChart = newTimelineChart()
|
||||
|
||||
timelineChart.container.connectToParent(thisObject.container, true, true)
|
||||
timelineChart.container.connectToParent(thisObject.container, true, true, false, true, true, true)
|
||||
timelineChart.container.frame.height = thisObject.container.frame.height
|
||||
|
||||
timelineChart.container.frame.position.x = thisObject.container.frame.width / 2 - timelineChart.container.frame.width / 2
|
||||
@@ -103,32 +103,44 @@ function newTimeMachine () {
|
||||
controlPanel.container.eventHandler.listenToEvent('Datetime Changed', timelineChart.setDatetime, undefined)
|
||||
timelineChart.container.eventHandler.listenToEvent('Datetime Changed', controlPanel.setDatetime)
|
||||
|
||||
/* Each Time Machine has a Time Scale and a Right Scale. */
|
||||
/* Each Time Machine has a Time Scale and a Right Scale. */
|
||||
|
||||
timeScale = newTimeScale()
|
||||
timeScale.container.connectToParent(thisObject.container, false, false)
|
||||
timeScale.container.eventHandler.listenToEvent('Lenght Percentage Changed', function (event) {
|
||||
thisObject.timeScale = newTimeScale()
|
||||
|
||||
thisObject.timeScale.container.eventHandler.listenToEvent('Lenght Percentage Changed', function (event) {
|
||||
thisObject.container.frame.width = TIME_MACHINE_WIDTH * event.lenghtPercentage / 100
|
||||
recalculateScale()
|
||||
moveToUserPosition(thisObject.container, timeLineCoordinateSystem, false, true, event.mousePosition)
|
||||
thisObject.container.eventHandler.raiseEvent('Dimmensions Changed', event)
|
||||
})
|
||||
|
||||
timeScale.initialize(timeLineCoordinateSystem)
|
||||
thisObject.timeScale.initialize()
|
||||
|
||||
rigthScale = newRateScale()
|
||||
rigthScale.container.connectToParent(thisObject.container, false, false)
|
||||
rigthScale.container.eventHandler.listenToEvent('Height Percentage Changed', function (event) {
|
||||
thisObject.rateScale = newRateScale()
|
||||
|
||||
thisObject.rateScale.container.eventHandler.listenToEvent('Height Percentage Changed', function (event) {
|
||||
thisObject.container.frame.height = TIME_MACHINE_HEIGHT * event.heightPercentage / 100
|
||||
recalculateScale()
|
||||
moveToUserPosition(thisObject.container, timeLineCoordinateSystem, true, false, event.mousePosition)
|
||||
thisObject.container.eventHandler.raiseEvent('Dimmensions Changed', event)
|
||||
})
|
||||
|
||||
rigthScale.initialize(timeLineCoordinateSystem)
|
||||
thisObject.rateScale.initialize()
|
||||
|
||||
thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver)
|
||||
|
||||
initializeTheRest()
|
||||
}
|
||||
|
||||
function initializeTheRest () {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] initialize -> initializeTheRest -> Entering function.') }
|
||||
function onMouseOver (event) {
|
||||
thisObject.timeScale.visible = true
|
||||
thisObject.rateScale.visible = true
|
||||
|
||||
mouse.position.x = event.x
|
||||
mouse.position.y = event.y
|
||||
}
|
||||
|
||||
function initializeTheRest () {
|
||||
let leftToInitialize = SUPPORTED_EXCHANGES.length * SUPPORTED_MARKETS.length - 1 // The default exchange and market was already initialized.
|
||||
let alreadyInitialized = 0
|
||||
|
||||
@@ -143,21 +155,19 @@ function newTimeMachine () {
|
||||
let market = SUPPORTED_MARKETS[j]
|
||||
|
||||
if (
|
||||
exchange === DEFAULT_EXCHANGE &&
|
||||
market.assetA === DEFAULT_MARKET.assetA &&
|
||||
market.assetB === DEFAULT_MARKET.assetB
|
||||
) { continue }
|
||||
exchange === DEFAULT_EXCHANGE &&
|
||||
market.assetA === DEFAULT_MARKET.assetA &&
|
||||
market.assetB === DEFAULT_MARKET.assetB
|
||||
) { continue }
|
||||
|
||||
initializeTimelineChart(exchange, market)
|
||||
}
|
||||
}
|
||||
|
||||
function initializeTimelineChart (exchange, market) {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] initialize -> initializeTheRest -> initializeTimelineChart -> Entering function.') }
|
||||
|
||||
let timelineChart = newTimelineChart()
|
||||
|
||||
timelineChart.container.connectToParent(thisObject.container, true, true)
|
||||
timelineChart.container.connectToParent(thisObject.container, true, true, false, true, true, true)
|
||||
|
||||
timelineChart.container.frame.height = thisObject.container.frame.height
|
||||
|
||||
@@ -169,8 +179,6 @@ function newTimeMachine () {
|
||||
timelineChart.initialize(exchange, market, timeLineCoordinateSystem, finalSteps)
|
||||
|
||||
function finalSteps () {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] initialize -> initializeTheRest -> initializeTimelineChart -> finalSteps -> Entering function.') }
|
||||
|
||||
thisObject.charts.push(timelineChart)
|
||||
|
||||
controlPanel.container.eventHandler.listenToEvent('Datetime Changed', timelineChart.setDatetime, undefined)
|
||||
@@ -186,32 +194,11 @@ function newTimeMachine () {
|
||||
}
|
||||
}
|
||||
|
||||
function drawBackground () {
|
||||
for (let i = 0; i < this.charts.length; i++) {
|
||||
let chart = this.charts[i]
|
||||
chart.drawBackground()
|
||||
}
|
||||
}
|
||||
|
||||
function draw () {
|
||||
if (thisObject.container.frame.isInViewPort()) {
|
||||
for (let i = 0; i < this.charts.length; i++) {
|
||||
let chart = this.charts[i]
|
||||
chart.draw()
|
||||
}
|
||||
|
||||
if (timeScale !== undefined) { timeScale.draw() }
|
||||
if (rigthScale !== undefined) { rigthScale.draw() }
|
||||
|
||||
// thisObject.container.frame.draw(false, true, false)
|
||||
}
|
||||
}
|
||||
|
||||
function getContainer (point, purpose) {
|
||||
let container
|
||||
|
||||
if (timeScale !== undefined) {
|
||||
container = timeScale.getContainer(point)
|
||||
if (thisObject.timeScale !== undefined) {
|
||||
container = thisObject.timeScale.getContainer(point)
|
||||
if (container !== undefined) {
|
||||
if (container.isForThisPurpose(purpose)) {
|
||||
return container
|
||||
@@ -219,8 +206,8 @@ function newTimeMachine () {
|
||||
}
|
||||
}
|
||||
|
||||
if (rigthScale !== undefined) {
|
||||
container = rigthScale.getContainer(point)
|
||||
if (thisObject.rateScale !== undefined) {
|
||||
container = thisObject.rateScale.getContainer(point)
|
||||
if (container !== undefined) {
|
||||
if (container.isForThisPurpose(purpose)) {
|
||||
return container
|
||||
@@ -232,7 +219,9 @@ function newTimeMachine () {
|
||||
container = this.charts[i].getContainer(point)
|
||||
if (container !== undefined) {
|
||||
if (container.isForThisPurpose(purpose)) {
|
||||
return container
|
||||
if (thisObject.container.frame.isThisPointHere(point) === true) {
|
||||
return container
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -242,14 +231,132 @@ function newTimeMachine () {
|
||||
} else {
|
||||
if (purpose === GET_CONTAINER_PURPOSE.MOUSE_OVER) {
|
||||
thisObject.container.eventHandler.raiseEvent('onMouseNotOver')
|
||||
thisObject.timeScale.visible = false
|
||||
thisObject.rateScale.visible = false
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
function recalculateScale () {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] recalculateScale -> Entering function.') }
|
||||
function physics () {
|
||||
thisObjectPhysics()
|
||||
childrenPhysics()
|
||||
}
|
||||
|
||||
function thisObjectPhysics () {
|
||||
/* Screen Corner Date Calculation */
|
||||
|
||||
let point = {
|
||||
x: 0,
|
||||
y: 0
|
||||
}
|
||||
|
||||
let cornerDate = getDateFromPoint(point, thisObject.container, timeLineCoordinateSystem)
|
||||
cornerDate = new Date(cornerDate)
|
||||
window.localStorage.setItem('Date @ Screen Corner', cornerDate.toUTCString())
|
||||
}
|
||||
|
||||
function childrenPhysics () {
|
||||
thisObject.timeScale.physics()
|
||||
thisObject.rateScale.physics()
|
||||
|
||||
for (let i = 0; i < thisObject.charts.length; i++) {
|
||||
let chart = thisObject.charts[i]
|
||||
chart.physics()
|
||||
}
|
||||
|
||||
/* Mouse Position Date Calculation */
|
||||
|
||||
let timePoint = {
|
||||
x: mouse.position.x,
|
||||
y: 0
|
||||
}
|
||||
|
||||
let mouseDate = getDateFromPoint(timePoint, thisObject.container, timeLineCoordinateSystem)
|
||||
|
||||
thisObject.timeScale.date = new Date(mouseDate)
|
||||
|
||||
/* Mouse Position Rate Calculation */
|
||||
|
||||
let ratePoint = {
|
||||
x: 0,
|
||||
y: mouse.position.y
|
||||
}
|
||||
|
||||
let mouseRate = getRateFromPoint(ratePoint, thisObject.container, timeLineCoordinateSystem)
|
||||
|
||||
thisObject.rateScale.rate = mouseRate
|
||||
|
||||
/* timeScale Positioning */
|
||||
|
||||
thisObject.timeScale.container.frame.position.x = mouse.position.x - thisObject.timeScale.container.frame.width / 2
|
||||
|
||||
timePoint = {
|
||||
x: 0,
|
||||
y: 0
|
||||
}
|
||||
|
||||
timePoint = transformThisPoint(timePoint, thisObject.container.frame.container)
|
||||
timePoint = thisObject.container.fitFunction(timePoint)
|
||||
|
||||
thisObject.timeScale.container.frame.position.y = timePoint.y
|
||||
|
||||
/* rateScale Positioning */
|
||||
|
||||
thisObject.rateScale.container.frame.position.y = mouse.position.y - thisObject.rateScale.container.frame.height / 2
|
||||
|
||||
ratePoint = {
|
||||
x: 10000000000000,
|
||||
y: 0
|
||||
}
|
||||
|
||||
ratePoint = transformThisPoint(ratePoint, thisObject.container.frame.container)
|
||||
ratePoint = thisObject.container.fitFunction(ratePoint)
|
||||
|
||||
thisObject.rateScale.container.frame.position.x = ratePoint.x - thisObject.rateScale.container.frame.width
|
||||
}
|
||||
|
||||
function drawBackground () {
|
||||
thisBackground()
|
||||
|
||||
if (thisObject.container.frame.isInViewPort()) {
|
||||
for (let i = 0; i < this.charts.length; i++) {
|
||||
let chart = this.charts[i]
|
||||
chart.drawBackground()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function draw () {
|
||||
if (thisObject.container.frame.isInViewPort()) {
|
||||
for (let i = 0; i < this.charts.length; i++) {
|
||||
let chart = this.charts[i]
|
||||
chart.draw()
|
||||
}
|
||||
|
||||
if (thisObject.timeScale !== undefined) { thisObject.timeScale.draw() }
|
||||
if (thisObject.rateScale !== undefined) { thisObject.rateScale.draw() }
|
||||
|
||||
// thisObject.container.frame.draw(false, true, false)
|
||||
}
|
||||
}
|
||||
|
||||
function thisBackground () {
|
||||
let params = {
|
||||
cornerRadius: 15,
|
||||
lineWidth: 5,
|
||||
opacity: 1,
|
||||
container: thisObject.container,
|
||||
borderColor: UI_COLOR.RUSTED_RED,
|
||||
backgroundColor: UI_COLOR.WHITE,
|
||||
fitFunction: thisObject.fitFunction,
|
||||
coordinateSystem: timeLineCoordinateSystem
|
||||
}
|
||||
|
||||
roundedCornersBackground(params)
|
||||
}
|
||||
|
||||
function recalculateScale () {
|
||||
let minValue = {
|
||||
x: MIN_PLOTABLE_DATE.valueOf(),
|
||||
y: 0
|
||||
@@ -261,10 +368,10 @@ function newTimeMachine () {
|
||||
}
|
||||
|
||||
timeLineCoordinateSystem.initialize(
|
||||
minValue,
|
||||
maxValue,
|
||||
thisObject.container.frame.width,
|
||||
thisObject.container.frame.height
|
||||
)
|
||||
minValue,
|
||||
maxValue,
|
||||
thisObject.container.frame.width,
|
||||
thisObject.container.frame.height
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,525 @@
|
||||
function newTimelineChart () {
|
||||
const MODULE_NAME = 'Timeline Chart'
|
||||
const INFO_LOG = false
|
||||
const INTENSIVE_LOG = false
|
||||
const ERROR_LOG = true
|
||||
const logger = newWebDebugLog()
|
||||
logger.fileName = MODULE_NAME
|
||||
|
||||
let timeLineCoordinateSystem
|
||||
|
||||
let timePeriod = INITIAL_TIME_PERIOD
|
||||
let datetime = NEW_SESSION_INITIAL_DATE
|
||||
|
||||
let thisObject = {
|
||||
container: undefined,
|
||||
fitFunction: undefined,
|
||||
physics: physics,
|
||||
setDatetime: setDatetime,
|
||||
drawBackground: drawBackground,
|
||||
draw: draw,
|
||||
getContainer: getContainer,
|
||||
initialize: initialize,
|
||||
finalize: finalize
|
||||
}
|
||||
|
||||
thisObject.container = newContainer()
|
||||
thisObject.container.initialize(MODULE_NAME)
|
||||
thisObject.container.detectMouseOver = true
|
||||
|
||||
thisObject.fitFunction = canvas.chartSpace.fitIntoVisibleArea
|
||||
|
||||
let initializationReady = false
|
||||
|
||||
let productsPanel
|
||||
|
||||
/* Background */
|
||||
let logoAssetA
|
||||
let logoAssetB
|
||||
let logoExchange
|
||||
let logoAA
|
||||
let canDrawLogoA = false
|
||||
let canDrawLogoB = false
|
||||
let canDrawLogoExchange = false
|
||||
let canDrawLogoAA = false
|
||||
|
||||
let plotterManager
|
||||
let exchange
|
||||
let market
|
||||
|
||||
let productsPanelHandle
|
||||
let timePeriodScale
|
||||
|
||||
return thisObject
|
||||
|
||||
function finalize () {
|
||||
try {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] finalize -> Entering function.') }
|
||||
|
||||
plotterManager.finalize()
|
||||
} catch (err) {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] finalize -> err = ' + err.stack) }
|
||||
}
|
||||
}
|
||||
|
||||
function initialize (pExchange, pMarket, pTimeLineCoordinateSystem, callBackFunction) {
|
||||
try {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] initialize -> Entering function.') }
|
||||
|
||||
/* We load the logow we will need for the background. */
|
||||
exchange = pExchange
|
||||
market = pMarket
|
||||
timeLineCoordinateSystem = pTimeLineCoordinateSystem
|
||||
|
||||
thisObject.container.eventHandler.listenToEvent('onMouseOver', function (event) {
|
||||
saveUserPosition(thisObject.container, timeLineCoordinateSystem, event)
|
||||
})
|
||||
|
||||
let panelOwner = exchange + ' ' + market.assetB + '/' + market.assetA
|
||||
productsPanelHandle = canvas.panelsSpace.createNewPanel('Products Panel', undefined, panelOwner)
|
||||
let productsPanel = canvas.panelsSpace.getPanel(productsPanelHandle, panelOwner)
|
||||
productsPanel.initialize(exchange, market)
|
||||
|
||||
logoA = new Image()
|
||||
logoB = new Image()
|
||||
logoExchange = new Image()
|
||||
logoAA = new Image()
|
||||
|
||||
logoA.onload = onImageALoaded
|
||||
|
||||
function onImageALoaded () {
|
||||
canDrawLogoA = true
|
||||
}
|
||||
|
||||
logoB.onload = onImageBLoaded
|
||||
|
||||
function onImageBLoaded () {
|
||||
canDrawLogoB = true
|
||||
}
|
||||
|
||||
logoExchange.onload = onImageExchangeLoaded
|
||||
|
||||
function onImageExchangeLoaded () {
|
||||
canDrawLogoExchange = true
|
||||
}
|
||||
|
||||
logoAA.onload = onImageAALoaded
|
||||
|
||||
function onImageAALoaded () {
|
||||
canDrawLogoAA = true
|
||||
}
|
||||
|
||||
logoA.src = window.canvasApp.urlPrefix + 'Images/tether-logo-background.png'
|
||||
logoB.src = window.canvasApp.urlPrefix + 'Images/bitcoin-logo-background.png'
|
||||
logoExchange.src = window.canvasApp.urlPrefix + 'Images/' + exchange + '-logo-background.png'
|
||||
logoAA.src = window.canvasApp.urlPrefix + 'Images/sa-logo-background.png'
|
||||
|
||||
// moveToUserPosition(thisObject.container, timeLineCoordinateSystem, undefined, undefined, undefined, true)
|
||||
timePeriod = INITIAL_TIME_PERIOD
|
||||
datetime = NEW_SESSION_INITIAL_DATE
|
||||
|
||||
/* Event Subscriptions - we need this events to be fired first here and then in active Plotters. */
|
||||
|
||||
viewPort.eventHandler.listenToEvent('Offset Changed', onOffsetChanged)
|
||||
viewPort.eventHandler.listenToEvent('Zoom Changed', onZoomChanged)
|
||||
|
||||
/* Initialize the Plotter Manager */
|
||||
|
||||
plotterManager = newPlottersManager()
|
||||
|
||||
plotterManager.container.connectToParent(thisObject.container, true, true, false, true, true, true)
|
||||
|
||||
plotterManager.container.frame.position.x = 0
|
||||
plotterManager.container.frame.position.y = 0
|
||||
|
||||
plotterManager.initialize(productsPanel, pExchange, pMarket, onPlotterManagerReady)
|
||||
|
||||
function onPlotterManagerReady (err) {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] initialize -> onPlotterManagerReady -> Entering function.') }
|
||||
|
||||
if (err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> onPlotterManagerReady -> Plotter Manager Initialization Failed. ') }
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> onPlotterManagerReady -> err= ' + err.stack) }
|
||||
|
||||
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
|
||||
return
|
||||
}
|
||||
|
||||
timePeriodScale = newTimePeriodScale()
|
||||
timePeriodScale.container.connectToParent(thisObject.container, false, false, false, true, true, true)
|
||||
timePeriodScale.container.eventHandler.listenToEvent('Time Period Changed', function (event) {
|
||||
let currentTimePeriod = timePeriod
|
||||
timePeriod = event.timePeriod
|
||||
if (timePeriod !== currentTimePeriod) {
|
||||
plotterManager.setTimePeriod(timePeriod)
|
||||
}
|
||||
})
|
||||
|
||||
timePeriodScale.initialize(timeLineCoordinateSystem)
|
||||
|
||||
initializationReady = true
|
||||
callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE)
|
||||
return
|
||||
}
|
||||
} catch (err) {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> err = ' + err.stack) }
|
||||
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
|
||||
}
|
||||
}
|
||||
|
||||
function onZoomChanged (event) {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] onZoomChanged -> Entering function.') }
|
||||
|
||||
if (initializationReady === true) {
|
||||
recalculateCurrentDatetime()
|
||||
|
||||
// saveUserPosition(thisObject.container, timeLineCoordinateSystem)
|
||||
}
|
||||
}
|
||||
|
||||
function setDatetime (pDatetime) {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] setDatetime -> Entering function.') }
|
||||
|
||||
/* This function is used when the time is changed through the user interface, but without zooming or panning. */
|
||||
/* No matter if the day changed or not, we need to inform all visible Plotters. */
|
||||
|
||||
if (thisObject.container.frame.isInViewPort()) {
|
||||
plotterManager.setDatetime(pDatetime)
|
||||
plotterManager.positionAtDatetime(pDatetime)
|
||||
}
|
||||
}
|
||||
|
||||
function onOffsetChanged () {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] onOffsetChanged -> Entering function.') }
|
||||
|
||||
if (initializationReady === true) {
|
||||
if (thisObject.container.frame.isInViewPort()) {
|
||||
recalculateCurrentDatetime()
|
||||
// saveUserPosition(thisObject.container, timeLineCoordinateSystem)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function recalculateCurrentDatetime () {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] recalculateCurrentDatetime -> Entering function.') }
|
||||
|
||||
/*
|
||||
|
||||
The view port was moved or the view port zoom level was changed and the center of the screen points to a different datetime that we
|
||||
must calculate.
|
||||
|
||||
*/
|
||||
|
||||
let center = {
|
||||
x: (viewPort.visibleArea.bottomRight.x - viewPort.visibleArea.bottomLeft.x) / 2,
|
||||
y: (viewPort.visibleArea.bottomRight.y - viewPort.visibleArea.topRight.y) / 2
|
||||
}
|
||||
|
||||
center = unTransformThisPoint(center, thisObject.container)
|
||||
center = timeLineCoordinateSystem.unInverseTransform(center, thisObject.container.frame.height)
|
||||
|
||||
let newDate = new Date(0)
|
||||
newDate.setUTCSeconds(center.x / 1000)
|
||||
|
||||
datetime = newDate
|
||||
|
||||
plotterManager.setDatetime(datetime)
|
||||
|
||||
thisObject.container.eventHandler.raiseEvent('Datetime Changed', datetime)
|
||||
}
|
||||
|
||||
function getContainer (point) {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] getContainer -> Entering function.') }
|
||||
|
||||
let container
|
||||
|
||||
container = timePeriodScale.getContainer(point)
|
||||
|
||||
if (container !== undefined) { return container }
|
||||
|
||||
return container
|
||||
}
|
||||
|
||||
function physics () {
|
||||
thisObjectPhysics()
|
||||
childrenPhysics()
|
||||
}
|
||||
|
||||
function thisObjectPhysics () {
|
||||
|
||||
}
|
||||
|
||||
function childrenPhysics () {
|
||||
|
||||
}
|
||||
|
||||
function tooTiny () {
|
||||
if (viewPort.zoomLevel < Math.trunc(-28.25 * 100) / 100) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
function tooSmall () {
|
||||
if (viewPort.zoomLevel < Math.trunc(-27.25 * 100) / 100) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
function drawBackground () {
|
||||
if (thisObject.container.frame.isInViewPort()) {
|
||||
if (window.CHART_ON_FOCUS === '') {
|
||||
window.CHART_ON_FOCUS = exchange + ' ' + market.assetB + '/' + market.assetA
|
||||
|
||||
drawChartsBackgroundImages()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function draw () {
|
||||
if (thisObject.container.frame.isInViewPort()) {
|
||||
drawChartsBackground()
|
||||
plotterManager.draw()
|
||||
timePeriodScale.draw()
|
||||
}
|
||||
}
|
||||
|
||||
function drawChartsBackground () {
|
||||
/* We will paint some transparent background here. */
|
||||
|
||||
let opacity = '0.9'
|
||||
|
||||
let fromPoint = {
|
||||
x: 0,
|
||||
y: 0
|
||||
}
|
||||
|
||||
let toPoint = {
|
||||
x: thisObject.container.frame.width,
|
||||
y: thisObject.container.frame.height
|
||||
}
|
||||
|
||||
fromPoint = transformThisPoint(fromPoint, thisObject.container)
|
||||
toPoint = transformThisPoint(toPoint, thisObject.container)
|
||||
|
||||
fromPoint = canvas.chartSpace.fitIntoVisibleArea(fromPoint)
|
||||
toPoint = canvas.chartSpace.fitIntoVisibleArea(toPoint)
|
||||
|
||||
browserCanvasContext.beginPath()
|
||||
|
||||
browserCanvasContext.rect(fromPoint.x, fromPoint.y, toPoint.x - fromPoint.x, toPoint.y - fromPoint.y)
|
||||
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + opacity + ')'
|
||||
|
||||
browserCanvasContext.closePath()
|
||||
|
||||
browserCanvasContext.fill()
|
||||
}
|
||||
|
||||
function drawChartsBackgroundImages () {
|
||||
if (canDrawLogoA === false || canDrawLogoB === false || canDrawLogoExchange === false || canDrawLogoAA === false) { return }
|
||||
|
||||
/* Fist we calculate the corners of the current frame so as not to draw imaages ourside of it */
|
||||
|
||||
let fromPoint = {
|
||||
x: 0,
|
||||
y: 0
|
||||
}
|
||||
|
||||
let toPoint = {
|
||||
x: thisObject.container.frame.width,
|
||||
y: thisObject.container.frame.height
|
||||
}
|
||||
|
||||
fromPoint = transformThisPoint(fromPoint, thisObject.container)
|
||||
toPoint = transformThisPoint(toPoint, thisObject.container)
|
||||
|
||||
/* Second we calculate the points for the images themselves */
|
||||
|
||||
let backgroundLogoPoint1
|
||||
let backgroundLogoPoint2
|
||||
|
||||
let imageHeight = 42
|
||||
let imageWidth = 150
|
||||
|
||||
const MAX_COLUMNS = 16
|
||||
const MAX_ROWS = 5
|
||||
const Y_TOP_MARGIN = 30
|
||||
const MIN_ROW_HIGHT = 100
|
||||
|
||||
let point1 = {
|
||||
x: viewPort.visibleArea.topLeft.x,
|
||||
y: viewPort.visibleArea.topLeft.y
|
||||
}
|
||||
|
||||
backgroundLogoPoint1 = {
|
||||
x: getDateFromPoint(point1, thisObject.container, timeLineCoordinateSystem).valueOf(),
|
||||
y: getRateFromPoint(point1, thisObject.container, timeLineCoordinateSystem)
|
||||
}
|
||||
|
||||
let point2 = {
|
||||
x: viewPort.visibleArea.topLeft.x + imageWidth * 8,
|
||||
y: viewPort.visibleArea.topLeft.y
|
||||
}
|
||||
|
||||
backgroundLogoPoint2 = {
|
||||
x: getDateFromPoint(point2, thisObject.container, timeLineCoordinateSystem).valueOf(),
|
||||
y: getRateFromPoint(point2, thisObject.container, timeLineCoordinateSystem)
|
||||
}
|
||||
|
||||
let currentCorner = {
|
||||
x: getDateFromPoint(viewPort.visibleArea.topLeft, thisObject.container, timeLineCoordinateSystem).valueOf(),
|
||||
y: getRateFromPoint(viewPort.visibleArea.topLeft, thisObject.container, timeLineCoordinateSystem)
|
||||
}
|
||||
|
||||
currentCorner.x = Math.trunc(currentCorner.x / (backgroundLogoPoint2.x - backgroundLogoPoint1.x)) * (backgroundLogoPoint2.x - backgroundLogoPoint1.x)
|
||||
|
||||
let rowHight = (viewPort.visibleArea.bottomLeft.y - viewPort.visibleArea.topLeft.y) / 4.5
|
||||
if (rowHight < MIN_ROW_HIGHT) { rowHight = MIN_ROW_HIGHT }
|
||||
|
||||
imagePoint = timeLineCoordinateSystem.transformThisPoint(currentCorner)
|
||||
imagePoint = transformThisPoint(imagePoint, thisObject.container)
|
||||
|
||||
let offSet = 0
|
||||
let imagePosition = {
|
||||
x: 0,
|
||||
y: 0
|
||||
}
|
||||
|
||||
for (let j = 0; j < MAX_ROWS; j++) {
|
||||
if (offSet === -imageWidth * 8) {
|
||||
offSet = -imageWidth * 4 - imageWidth
|
||||
} else {
|
||||
offSet = -imageWidth * 8
|
||||
}
|
||||
|
||||
for (let i = 0; i < MAX_COLUMNS; i = i + 4) {
|
||||
let logo = logoA
|
||||
|
||||
imagePosition.x = imagePoint.x + i * imageWidth * 2 + offSet
|
||||
imagePosition.y = imagePoint.y + j * rowHight + Y_TOP_MARGIN
|
||||
|
||||
if (
|
||||
imagePosition.x > fromPoint.x &&
|
||||
imagePosition.x + imageWidth < toPoint.x &&
|
||||
imagePosition.y > fromPoint.y &&
|
||||
imagePosition.y + imageHeight < toPoint.y
|
||||
) {
|
||||
let checkPoint = {
|
||||
x: imagePosition.x,
|
||||
y: imagePosition.y + imageHeight
|
||||
}
|
||||
|
||||
checkPoint = thisObject.fitFunction(checkPoint)
|
||||
if (checkPoint.y === imagePosition.y + imageHeight) {
|
||||
browserCanvasContext.drawImage(logo, imagePosition.x, imagePosition.y, imageWidth, imageHeight)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
offSet = 0
|
||||
|
||||
for (let j = 0; j < MAX_ROWS; j++) {
|
||||
if (offSet === -imageWidth * 8) {
|
||||
offSet = -imageWidth * 4 - imageWidth
|
||||
} else {
|
||||
offSet = -imageWidth * 8
|
||||
}
|
||||
|
||||
for (let i = 1; i < MAX_COLUMNS; i = i + 4) {
|
||||
let logo = logoB
|
||||
|
||||
imagePosition.x = imagePoint.x + i * imageWidth * 2 + offSet
|
||||
imagePosition.y = imagePoint.y + j * rowHight + Y_TOP_MARGIN
|
||||
|
||||
if (
|
||||
imagePosition.x > fromPoint.x &&
|
||||
imagePosition.x + imageWidth < toPoint.x &&
|
||||
imagePosition.y > fromPoint.y &&
|
||||
imagePosition.y + imageHeight < toPoint.y
|
||||
) {
|
||||
let checkPoint = {
|
||||
x: imagePosition.x,
|
||||
y: imagePosition.y + imageHeight
|
||||
}
|
||||
|
||||
checkPoint = thisObject.fitFunction(checkPoint)
|
||||
if (checkPoint.y === imagePosition.y + imageHeight) {
|
||||
browserCanvasContext.drawImage(logo, imagePosition.x, imagePosition.y, imageWidth, imageHeight)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
offSet = 0
|
||||
|
||||
for (let j = 0; j < MAX_ROWS; j++) {
|
||||
if (offSet === -imageWidth * 8) {
|
||||
offSet = -imageWidth * 4 - imageWidth
|
||||
} else {
|
||||
offSet = -imageWidth * 8
|
||||
}
|
||||
|
||||
for (let i = 2; i < MAX_COLUMNS; i = i + 4) {
|
||||
let logo = logoExchange
|
||||
|
||||
imagePosition.x = imagePoint.x + i * imageWidth * 2 + offSet
|
||||
imagePosition.y = imagePoint.y + j * rowHight + Y_TOP_MARGIN
|
||||
|
||||
if (
|
||||
imagePosition.x > fromPoint.x &&
|
||||
imagePosition.x + imageWidth < toPoint.x &&
|
||||
imagePosition.y > fromPoint.y &&
|
||||
imagePosition.y + imageHeight < toPoint.y
|
||||
) {
|
||||
let checkPoint = {
|
||||
x: imagePosition.x,
|
||||
y: imagePosition.y + imageHeight
|
||||
}
|
||||
|
||||
checkPoint = thisObject.fitFunction(checkPoint)
|
||||
if (checkPoint.y === imagePosition.y + imageHeight) {
|
||||
browserCanvasContext.drawImage(logo, imagePosition.x, imagePosition.y, imageWidth, imageHeight)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
offSet = 0
|
||||
|
||||
for (let j = 0; j < MAX_ROWS; j++) {
|
||||
if (offSet === -imageWidth * 8) {
|
||||
offSet = -imageWidth * 4 - imageWidth
|
||||
} else {
|
||||
offSet = -imageWidth * 8
|
||||
}
|
||||
|
||||
for (let i = 3; i < MAX_COLUMNS; i = i + 4) {
|
||||
let logo = logoAA
|
||||
|
||||
imagePosition.x = imagePoint.x + i * imageWidth * 2 + offSet
|
||||
imagePosition.y = imagePoint.y + j * rowHight + Y_TOP_MARGIN
|
||||
|
||||
if (
|
||||
imagePosition.x > fromPoint.x &&
|
||||
imagePosition.x + imageWidth < toPoint.x &&
|
||||
imagePosition.y > fromPoint.y &&
|
||||
imagePosition.y + imageHeight < toPoint.y
|
||||
) {
|
||||
let checkPoint = {
|
||||
x: imagePosition.x,
|
||||
y: imagePosition.y + imageHeight
|
||||
}
|
||||
|
||||
checkPoint = thisObject.fitFunction(checkPoint)
|
||||
if (checkPoint.y === imagePosition.y + imageHeight) {
|
||||
browserCanvasContext.drawImage(logo, imagePosition.x, imagePosition.y, imageWidth, imageHeight)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
|
||||
|
||||
function newViewPort () {
|
||||
const MODULE_NAME = 'Viewport'
|
||||
const INFO_LOG = false
|
||||
@@ -10,11 +10,12 @@ function newViewPort () {
|
||||
const CONSOLE_LOG = true
|
||||
|
||||
let ANIMATION_INCREMENT = 0.25
|
||||
const TOP_MARGIN = 15 + TOP_SPACE_HEIGHT
|
||||
const BOTTOM_MARGIN = 15 + BOTTOM_SPACE_HEIGHT
|
||||
const LEFT_MARGIN = 50
|
||||
const RIGHT_MARGIN = 50
|
||||
const MARGINS = {
|
||||
|
||||
let TOP_MARGIN = 30 + TOP_SPACE_HEIGHT
|
||||
let BOTTOM_MARGIN = 30 + COCKPIT_SPACE_HEIGHT
|
||||
let LEFT_MARGIN = 50
|
||||
let RIGHT_MARGIN = 50
|
||||
let MARGINS = {
|
||||
TOP: TOP_MARGIN,
|
||||
BOTTOM: BOTTOM_MARGIN,
|
||||
LEFT: LEFT_MARGIN,
|
||||
@@ -23,6 +24,8 @@ function newViewPort () {
|
||||
|
||||
let thisObject = {
|
||||
visibleArea: undefined,
|
||||
width: undefined,
|
||||
height: undefined,
|
||||
eventHandler: undefined,
|
||||
zoomTargetLevel: undefined,
|
||||
zoomLevel: undefined,
|
||||
@@ -42,6 +45,7 @@ function newViewPort () {
|
||||
animate: animate,
|
||||
draw: draw,
|
||||
raiseEvents: raiseEvents,
|
||||
resize: resize,
|
||||
initialize: initialize
|
||||
}
|
||||
|
||||
@@ -74,6 +78,22 @@ function newViewPort () {
|
||||
return thisObject
|
||||
|
||||
function initialize () {
|
||||
resize()
|
||||
readObjectState()
|
||||
}
|
||||
|
||||
function resize () {
|
||||
TOP_MARGIN = 30 + TOP_SPACE_HEIGHT
|
||||
BOTTOM_MARGIN = 30 + browserCanvas.height - COCKPIT_SPACE_POSITION
|
||||
LEFT_MARGIN = 50
|
||||
RIGHT_MARGIN = 50
|
||||
MARGINS = {
|
||||
TOP: TOP_MARGIN,
|
||||
BOTTOM: BOTTOM_MARGIN,
|
||||
LEFT: LEFT_MARGIN,
|
||||
RIGHT: RIGHT_MARGIN
|
||||
}
|
||||
|
||||
thisObject.visibleArea = {
|
||||
topLeft: { x: LEFT_MARGIN, y: TOP_MARGIN },
|
||||
topRight: { x: browserCanvas.width - RIGHT_MARGIN, y: TOP_MARGIN },
|
||||
@@ -81,7 +101,8 @@ function newViewPort () {
|
||||
bottomLeft: { x: LEFT_MARGIN, y: browserCanvas.height - BOTTOM_MARGIN}
|
||||
}
|
||||
|
||||
readObjectState()
|
||||
thisObject.width = thisObject.visibleArea.topRight.x - thisObject.visibleArea.topLeft.x
|
||||
thisObject.height = thisObject.visibleArea.bottomRight.y - thisObject.visibleArea.topLeft.y
|
||||
}
|
||||
|
||||
function getDisplacement () {
|
||||
@@ -121,7 +142,7 @@ function newViewPort () {
|
||||
if (Math.trunc(Math.abs(targetOffset.y - offset.y) * 1000) >= Math.trunc(Math.abs(offsetIncrement.y) * 1000)) {
|
||||
offset.y = offset.y + offsetIncrement.y
|
||||
|
||||
// console.log("offset.y changed to " + offset.y)
|
||||
// console.log("offset.y changed to " + offset.y)
|
||||
} else {
|
||||
offsetIncrement.y = 0
|
||||
}
|
||||
@@ -140,7 +161,7 @@ function newViewPort () {
|
||||
|
||||
thisObject.eventHandler.raiseEvent('Offset Changed', event)
|
||||
|
||||
// console.log("displace produced new Offset x = " + offset.x + " y = " + offset.y);
|
||||
// console.log("displace produced new Offset x = " + offset.x + " y = " + offset.y);
|
||||
}
|
||||
|
||||
function displaceTarget (displaceVector) {
|
||||
@@ -152,7 +173,7 @@ function newViewPort () {
|
||||
y: (targetOffset.y - offset.y) / 10
|
||||
}
|
||||
|
||||
// console.log("displaceTarget x = " + targetOffset.x + " y = " + targetOffset.y);
|
||||
// console.log("displaceTarget x = " + targetOffset.x + " y = " + targetOffset.y);
|
||||
}
|
||||
|
||||
function newZoomLevel (level) {
|
||||
@@ -175,13 +196,13 @@ function newViewPort () {
|
||||
}
|
||||
|
||||
function isMinZoom () {
|
||||
/* returns true is we are currently at the min zoom level. */
|
||||
/* returns true is we are currently at the min zoom level. */
|
||||
|
||||
if (thisObject.zoomTargetLevel === MIN_ZOOM_LEVEL) { return true } else { return false }
|
||||
}
|
||||
|
||||
function applyZoom (amount) {
|
||||
// console.log("applyZoom amount: " + amount);
|
||||
// console.log("applyZoom amount: " + amount);
|
||||
|
||||
if (amount > 0) {
|
||||
if (thisObject.zoomTargetLevel > -5) {
|
||||
@@ -279,7 +300,7 @@ function newViewPort () {
|
||||
}
|
||||
|
||||
function fitIntoVisibleArea (point) {
|
||||
/* Here we check the boundaries of the resulting points, so they dont go out of the visible area. */
|
||||
/* Here we check the boundaries of the resulting points, so they dont go out of the visible area. */
|
||||
|
||||
if (point.x > thisObject.visibleArea.bottomRight.x + 1) {
|
||||
point.x = thisObject.visibleArea.bottomRight.x + 1
|
||||
@@ -432,3 +453,4 @@ function newViewPort () {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
|
||||
function newAssetBalances () {
|
||||
const MODULE_NAME = 'Asset Balances'
|
||||
|
||||
let thisObject = {
|
||||
visible: true,
|
||||
container: undefined,
|
||||
paramsArray: undefined,
|
||||
setParamsArray: setParamsArray,
|
||||
physics: physics,
|
||||
draw: draw,
|
||||
speedometers: [],
|
||||
getContainer: getContainer,
|
||||
initialize: initialize,
|
||||
finalize: finalize
|
||||
}
|
||||
|
||||
thisObject.container = newContainer()
|
||||
thisObject.container.initialize(MODULE_NAME)
|
||||
|
||||
thisObject.container.isDraggeable = false
|
||||
thisObject.container.isWheelable = false
|
||||
|
||||
return thisObject
|
||||
|
||||
function finalize () {
|
||||
for (let i = 0; i < thisObject.speedometers.length; i++) {
|
||||
let speedometer = thisObject.speedometers[i]
|
||||
speedometer.finalize()
|
||||
}
|
||||
thisObject.container.finalize()
|
||||
thisObject.container = undefined
|
||||
thisObject.paramsArray = undefined
|
||||
}
|
||||
|
||||
function initialize () {
|
||||
for (let i = 0; i < 2; i++) {
|
||||
let speedometer = newSpeedometer()
|
||||
|
||||
speedometer.container.frame.position.x = thisObject.container.frame.width / 2 - speedometer.container.frame.width / 2
|
||||
speedometer.container.frame.position.y = thisObject.container.frame.height / 2 - speedometer.container.frame.height / 2
|
||||
|
||||
speedometer.initialize()
|
||||
thisObject.speedometers.push(speedometer)
|
||||
}
|
||||
}
|
||||
|
||||
function getContainer (point, purpose) {
|
||||
if (thisObject.visible !== true) { return }
|
||||
|
||||
let container
|
||||
for (let i = 0; i < thisObject.speedometers.length; i++) {
|
||||
container = thisObject.speedometers[i].getContainer(point, purpose)
|
||||
if (container !== undefined) {
|
||||
if (container.isForThisPurpose(purpose)) {
|
||||
if (thisObject.container.frame.isThisPointHere(point, true) === true) {
|
||||
return container
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (thisObject.container.frame.isThisPointHere(point, true) === true) {
|
||||
return thisObject.container
|
||||
} else {
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
function setParamsArray (paramsArray) {
|
||||
thisObject.paramsArray = paramsArray
|
||||
for (let i = 0; i < thisObject.speedometers.length; i++) {
|
||||
let speedometer = thisObject.speedometers[i]
|
||||
speedometer.params = paramsArray[i]
|
||||
}
|
||||
}
|
||||
|
||||
function physics () {
|
||||
|
||||
}
|
||||
|
||||
function draw () {
|
||||
if (thisObject.visible !== true) { return }
|
||||
|
||||
for (let i = 0; i < thisObject.speedometers.length; i++) {
|
||||
let speedometer = thisObject.speedometers[i]
|
||||
speedometer.draw()
|
||||
}
|
||||
|
||||
drawAssetBalances()
|
||||
}
|
||||
|
||||
function drawAssetBalances () {
|
||||
if (thisObject.paramsArray === undefined) { return }
|
||||
|
||||
let fontSize
|
||||
let label
|
||||
let xOffset
|
||||
let yOffset
|
||||
|
||||
const OPACITY = 1
|
||||
|
||||
/* We put the params.VALUE in the middle */
|
||||
|
||||
fontSize = 15
|
||||
|
||||
browserCanvasContext.font = 'bold ' + fontSize + 'px ' + UI_FONT.PRIMARY
|
||||
|
||||
label = 'ASSET BALANCES'
|
||||
|
||||
xOffset = label.length / 2 * fontSize * FONT_ASPECT_RATIO
|
||||
yOffset = -45
|
||||
|
||||
labelPoint = {
|
||||
x: 0 - xOffset + (thisObject.paramsArray[1].LEFT_OFFSET - thisObject.paramsArray[0].LEFT_OFFSET) / 2 + thisObject.paramsArray[0].LEFT_OFFSET - 20,
|
||||
y: COCKPIT_SPACE_POSITION - COCKPIT_SPACE_HEIGHT / 2 - yOffset
|
||||
}
|
||||
|
||||
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + OPACITY + ')'
|
||||
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
|
||||
async function graphQlRestartSimulation (simulationParams) {
|
||||
try {
|
||||
const accessToken = window.localStorage.getItem(LOGGED_IN_ACCESS_TOKEN_LOCAL_STORAGE_KEY)
|
||||
|
||||
if (accessToken === null) {
|
||||
throw new Error('Can not restart the simulation because the user is not logged in. ')
|
||||
}
|
||||
|
||||
const graphQLServer = await axios({
|
||||
url: window.canvasApp.graphQL.masterAppApiUrl,
|
||||
method: 'post',
|
||||
data: {
|
||||
query: `
|
||||
mutation operations_RunSimulation(
|
||||
$simulation: operations_SimulationInput)
|
||||
{
|
||||
operations_RunSimulation(simulation: $simulation)
|
||||
}
|
||||
`,
|
||||
variables: {
|
||||
simulation: simulationParams
|
||||
}
|
||||
},
|
||||
headers: {
|
||||
authorization: 'Bearer ' + accessToken
|
||||
}
|
||||
})
|
||||
|
||||
if (graphQLServer.data.errors) {
|
||||
console.log(err.stack)
|
||||
throw new Error(graphQLServer.data.errors[0].message)
|
||||
}
|
||||
} catch (err) {
|
||||
console.log(err.stack)
|
||||
throw new Error('There has been an error restarting the simulation. Error: ' + err.stack)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,216 @@
|
||||
|
||||
function newRestartSimulation () {
|
||||
const MODULE_NAME = 'Restart Simulation'
|
||||
|
||||
let thisObject = {
|
||||
visible: true,
|
||||
container: undefined,
|
||||
status: undefined,
|
||||
physics: physics,
|
||||
draw: draw,
|
||||
getContainer: getContainer,
|
||||
initialize: initialize,
|
||||
finalize: finalize
|
||||
}
|
||||
|
||||
thisObject.container = newContainer()
|
||||
thisObject.container.initialize(MODULE_NAME)
|
||||
|
||||
thisObject.container.isDraggeable = false
|
||||
thisObject.container.isWheelable = false
|
||||
thisObject.container.isClickeable = true
|
||||
thisObject.container.detectMouseOver = true
|
||||
|
||||
let selfMouseOverEventSubscriptionId
|
||||
let selfMouseClickEventSubscriptionId
|
||||
let selfMouseNotOverEventSubscriptionId
|
||||
|
||||
let isMouseOver = false
|
||||
let counterTillNextState = 0
|
||||
|
||||
return thisObject
|
||||
|
||||
function finalize () {
|
||||
thisObject.container.eventHandler.stopListening(selfMouseOverEventSubscriptionId)
|
||||
thisObject.container.eventHandler.stopListening(selfMouseClickEventSubscriptionId)
|
||||
thisObject.container.eventHandler.stopListening(selfMouseNotOverEventSubscriptionId)
|
||||
|
||||
thisObject.container.finalize()
|
||||
thisObject.container = undefined
|
||||
}
|
||||
|
||||
function initialize () {
|
||||
thisObject.container.frame.position.x = thisObject.container.parentContainer.frame.width * 80 / 100
|
||||
thisObject.container.frame.position.y = 6
|
||||
thisObject.container.frame.width = 250
|
||||
thisObject.container.frame.height = COCKPIT_SPACE_HEIGHT - 12
|
||||
|
||||
selfMouseOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver)
|
||||
selfMouseClickEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick)
|
||||
selfMouseNotOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver)
|
||||
|
||||
thisObject.status = 'Ready'
|
||||
}
|
||||
|
||||
function getContainer (point, purpose) {
|
||||
if (thisObject.visible !== true || thisObject.status !== 'Ready') { return }
|
||||
|
||||
if (thisObject.container.frame.isThisPointHere(point, true) === true) {
|
||||
return thisObject.container
|
||||
} else {
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
function onMouseOver (point) {
|
||||
if (thisObject.container.frame.isThisPointHere(point, true, false) === true) {
|
||||
isMouseOver = true
|
||||
} else {
|
||||
isMouseOver = false
|
||||
}
|
||||
}
|
||||
|
||||
function onMouseNotOver (point) {
|
||||
isMouseOver = false
|
||||
}
|
||||
|
||||
async function onMouseClick (event) {
|
||||
let dateAtScreenCorner = new Date(window.localStorage.getItem('Date @ Screen Corner'))
|
||||
let currentTimePeriod = JSON.parse(window.localStorage.getItem('Current Time Period'))
|
||||
|
||||
let timePeriodsMasterArray = [marketFilesPeriods, dailyFilePeriods]
|
||||
let timePeriodArray = timePeriodsMasterArray[currentTimePeriod.filePeriodIndex]
|
||||
let timePeriod = timePeriodArray[currentTimePeriod.timePeriodIndex][1]
|
||||
|
||||
let timePeriodDailyArray = []
|
||||
let timePeriodMarketArray = []
|
||||
|
||||
switch (currentTimePeriod.filePeriodIndex) {
|
||||
case 0: {
|
||||
timePeriodMarketArray.push(timePeriod)
|
||||
break
|
||||
}
|
||||
case 1: {
|
||||
timePeriodDailyArray.push(timePeriod)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
let simulationParams = {
|
||||
beginDatetime: dateAtScreenCorner.valueOf() / 1000 | 0,
|
||||
resumeExecution: false,
|
||||
timePeriodDailyArray: timePeriodDailyArray,
|
||||
timePeriodMarketArray: timePeriodMarketArray
|
||||
}
|
||||
try {
|
||||
thisObject.status = 'Restarting'
|
||||
await graphQlRestartSimulation(simulationParams)
|
||||
thisObject.status = 'Calculating'
|
||||
counterTillNextState = 1000
|
||||
} catch (err) {
|
||||
thisObject.status = 'Error'
|
||||
counterTillNextState = 500
|
||||
}
|
||||
}
|
||||
|
||||
function physics () {
|
||||
if (counterTillNextState > 0) {
|
||||
counterTillNextState--
|
||||
|
||||
if (counterTillNextState === 0) {
|
||||
switch (thisObject.status) {
|
||||
case 'Ready':
|
||||
|
||||
break
|
||||
case 'Restarting':
|
||||
|
||||
break
|
||||
case 'Calculating':
|
||||
thisObject.status = 'Ready'
|
||||
break
|
||||
case 'Error':
|
||||
thisObject.status = 'Ready'
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function draw () {
|
||||
if (thisObject.visible !== true) { return }
|
||||
drawBackground()
|
||||
drawText()
|
||||
}
|
||||
|
||||
function drawBackground () {
|
||||
let params = {
|
||||
cornerRadius: 3,
|
||||
lineWidth: 0.01,
|
||||
container: thisObject.container,
|
||||
borderColor: UI_COLOR.DARK,
|
||||
castShadow: false,
|
||||
opacity: 1
|
||||
}
|
||||
|
||||
switch (thisObject.status) {
|
||||
case 'Ready': {
|
||||
if (isMouseOver === true) {
|
||||
params.backgroundColor = UI_COLOR.TURQUOISE
|
||||
} else {
|
||||
params.backgroundColor = UI_COLOR.DARK_TURQUOISE
|
||||
}
|
||||
break
|
||||
}
|
||||
case 'Restarting':
|
||||
params.backgroundColor = UI_COLOR.GREY
|
||||
break
|
||||
case 'Calculating':
|
||||
params.backgroundColor = UI_COLOR.TITANIUM_YELLOW
|
||||
break
|
||||
case 'Error':
|
||||
params.backgroundColor = UI_COLOR.RUSTED_RED
|
||||
break
|
||||
}
|
||||
|
||||
roundedCornersBackground(params)
|
||||
}
|
||||
|
||||
function drawText () {
|
||||
let fontSize
|
||||
let label
|
||||
let xOffset
|
||||
let yOffset
|
||||
|
||||
const OPACITY = 1
|
||||
|
||||
/* We put the params.VALUE in the middle */
|
||||
|
||||
fontSize = 15
|
||||
|
||||
browserCanvasContext.font = 'bold ' + fontSize + 'px ' + UI_FONT.PRIMARY
|
||||
|
||||
switch (thisObject.status) {
|
||||
case 'Ready':
|
||||
label = 'RESTART SIMULATION'
|
||||
break
|
||||
case 'Restarting':
|
||||
label = 'RESTARTING...'
|
||||
break
|
||||
case 'Calculating':
|
||||
label = 'CALCULATING...'
|
||||
break
|
||||
case 'Error':
|
||||
label = 'NOT POSSIBLE NOW'
|
||||
break
|
||||
}
|
||||
|
||||
let labelPoint = {
|
||||
x: thisObject.container.frame.width / 2 - label.length / 2 * fontSize * FONT_ASPECT_RATIO - 15,
|
||||
y: thisObject.container.frame.height - 9
|
||||
}
|
||||
labelPoint = thisObject.container.frame.frameThisPoint(labelPoint)
|
||||
|
||||
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + OPACITY + ')'
|
||||
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,237 @@
|
||||
|
||||
function newSpeedometer () {
|
||||
const MODULE_NAME = 'Speedometer'
|
||||
|
||||
let thisObject = {
|
||||
visible: true,
|
||||
container: undefined,
|
||||
params: undefined,
|
||||
physics: physics,
|
||||
draw: draw,
|
||||
getContainer: getContainer,
|
||||
initialize: initialize,
|
||||
finalize: finalize
|
||||
}
|
||||
|
||||
thisObject.container = newContainer()
|
||||
thisObject.container.initialize(MODULE_NAME)
|
||||
|
||||
thisObject.container.isDraggeable = false
|
||||
thisObject.container.isWheelable = false
|
||||
|
||||
return thisObject
|
||||
|
||||
function finalize () {
|
||||
thisObject.container.finalize()
|
||||
thisObject.container = undefined
|
||||
thisObject.params = undefined
|
||||
}
|
||||
|
||||
function initialize () {
|
||||
|
||||
}
|
||||
|
||||
function getContainer (point, purpose) {
|
||||
if (thisObject.visible !== true) { return }
|
||||
|
||||
if (thisObject.container.frame.isThisPointHere(point, true) === true) {
|
||||
return thisObject.container
|
||||
} else {
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
function physics () {
|
||||
|
||||
}
|
||||
|
||||
function draw () {
|
||||
if (thisObject.params === undefined) { return }
|
||||
drawAssetCircle()
|
||||
}
|
||||
|
||||
function drawAssetCircle () {
|
||||
const RED_LINE_HIGHT = 5
|
||||
const RADIOUS = 50
|
||||
const OPACITY = 1
|
||||
|
||||
let centerPoint = {
|
||||
x: thisObject.params.LEFT_OFFSET,
|
||||
y: COCKPIT_SPACE_POSITION - COCKPIT_SPACE_HEIGHT / 2
|
||||
}
|
||||
|
||||
browserCanvasContext.beginPath()
|
||||
browserCanvasContext.arc(centerPoint.x, centerPoint.y, RADIOUS + RED_LINE_HIGHT, 0.85 * Math.PI, 2.15 * Math.PI)
|
||||
browserCanvasContext.closePath()
|
||||
|
||||
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.RUSTED_RED + ', ' + OPACITY + ')'
|
||||
browserCanvasContext.fill()
|
||||
|
||||
browserCanvasContext.beginPath()
|
||||
browserCanvasContext.arc(centerPoint.x, centerPoint.y, RADIOUS, 0.0 * Math.PI, 2.0 * Math.PI)
|
||||
browserCanvasContext.closePath()
|
||||
|
||||
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.DARK_TURQUOISE + ', ' + OPACITY + ')'
|
||||
browserCanvasContext.fill()
|
||||
|
||||
/* We draw the circle bar */
|
||||
|
||||
const DEFAULT_THICKNESS = 2
|
||||
const VALUE_THICKNESS = 8
|
||||
const VALUE_BG_THICKNESS = 1
|
||||
const BAR_RADIOUS = RADIOUS * 0.85
|
||||
|
||||
let BAR_START_ANGLE = 0.85 * Math.PI
|
||||
let BAR_END_ANGLE = 2.15 * Math.PI
|
||||
let CURRENT_VALUE_ANGLE = thisObject.params.VALUE * (BAR_END_ANGLE - BAR_START_ANGLE) / thisObject.params.MAX_VALUE + BAR_START_ANGLE
|
||||
let MIN_VALUE_ANGLE = thisObject.params.MIN_VALUE * (BAR_END_ANGLE - BAR_START_ANGLE) / thisObject.params.MAX_VALUE + BAR_START_ANGLE
|
||||
let INIT_VALUE_ANGLE = thisObject.params.INIT_VALUE * (BAR_END_ANGLE - BAR_START_ANGLE) / thisObject.params.MAX_VALUE + BAR_START_ANGLE
|
||||
let PROFIT_VALUE_ANGLE = CURRENT_VALUE_ANGLE
|
||||
|
||||
if (CURRENT_VALUE_ANGLE > INIT_VALUE_ANGLE) { CURRENT_VALUE_ANGLE = INIT_VALUE_ANGLE }
|
||||
|
||||
if (thisObject.params.VALUE > 0) {
|
||||
browserCanvasContext.setLineDash([0, 0])
|
||||
|
||||
browserCanvasContext.beginPath()
|
||||
browserCanvasContext.arc(centerPoint.x, centerPoint.y, BAR_RADIOUS, BAR_START_ANGLE, MIN_VALUE_ANGLE)
|
||||
|
||||
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', ' + OPACITY + ')'
|
||||
browserCanvasContext.lineWidth = VALUE_BG_THICKNESS
|
||||
browserCanvasContext.stroke()
|
||||
browserCanvasContext.closePath()
|
||||
|
||||
browserCanvasContext.beginPath()
|
||||
browserCanvasContext.arc(centerPoint.x, centerPoint.y, BAR_RADIOUS, MIN_VALUE_ANGLE, CURRENT_VALUE_ANGLE)
|
||||
|
||||
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + OPACITY + ')'
|
||||
browserCanvasContext.lineWidth = VALUE_BG_THICKNESS
|
||||
browserCanvasContext.stroke()
|
||||
browserCanvasContext.closePath()
|
||||
|
||||
browserCanvasContext.beginPath()
|
||||
browserCanvasContext.arc(centerPoint.x, centerPoint.y, BAR_RADIOUS, CURRENT_VALUE_ANGLE, INIT_VALUE_ANGLE)
|
||||
|
||||
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.RED + ', ' + OPACITY + ')'
|
||||
browserCanvasContext.lineWidth = VALUE_BG_THICKNESS
|
||||
browserCanvasContext.stroke()
|
||||
browserCanvasContext.closePath()
|
||||
|
||||
if (PROFIT_VALUE_ANGLE > INIT_VALUE_ANGLE) {
|
||||
browserCanvasContext.beginPath()
|
||||
browserCanvasContext.arc(centerPoint.x, centerPoint.y, BAR_RADIOUS, INIT_VALUE_ANGLE, PROFIT_VALUE_ANGLE)
|
||||
|
||||
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.GREEN + ', ' + OPACITY + ')'
|
||||
browserCanvasContext.lineWidth = VALUE_BG_THICKNESS
|
||||
browserCanvasContext.stroke()
|
||||
browserCanvasContext.closePath()
|
||||
}
|
||||
|
||||
browserCanvasContext.setLineDash([2, 3])
|
||||
|
||||
browserCanvasContext.beginPath()
|
||||
browserCanvasContext.arc(centerPoint.x, centerPoint.y, BAR_RADIOUS, BAR_START_ANGLE, MIN_VALUE_ANGLE)
|
||||
|
||||
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', ' + OPACITY + ')'
|
||||
browserCanvasContext.lineWidth = VALUE_THICKNESS
|
||||
browserCanvasContext.stroke()
|
||||
browserCanvasContext.closePath()
|
||||
|
||||
browserCanvasContext.beginPath()
|
||||
browserCanvasContext.arc(centerPoint.x, centerPoint.y, BAR_RADIOUS, MIN_VALUE_ANGLE, CURRENT_VALUE_ANGLE)
|
||||
|
||||
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + OPACITY + ')'
|
||||
browserCanvasContext.lineWidth = VALUE_THICKNESS
|
||||
browserCanvasContext.stroke()
|
||||
browserCanvasContext.closePath()
|
||||
|
||||
browserCanvasContext.beginPath()
|
||||
browserCanvasContext.arc(centerPoint.x, centerPoint.y, BAR_RADIOUS, CURRENT_VALUE_ANGLE, INIT_VALUE_ANGLE)
|
||||
|
||||
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.RED + ', ' + OPACITY + ')'
|
||||
browserCanvasContext.lineWidth = VALUE_THICKNESS
|
||||
browserCanvasContext.stroke()
|
||||
browserCanvasContext.closePath()
|
||||
|
||||
if (PROFIT_VALUE_ANGLE > INIT_VALUE_ANGLE) {
|
||||
browserCanvasContext.beginPath()
|
||||
browserCanvasContext.arc(centerPoint.x, centerPoint.y, BAR_RADIOUS, INIT_VALUE_ANGLE, PROFIT_VALUE_ANGLE)
|
||||
|
||||
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.GREEN + ', ' + OPACITY + ')'
|
||||
browserCanvasContext.lineWidth = VALUE_THICKNESS
|
||||
browserCanvasContext.stroke()
|
||||
browserCanvasContext.closePath()
|
||||
}
|
||||
}
|
||||
|
||||
/* Common Variables */
|
||||
|
||||
let fontSize
|
||||
let label
|
||||
let xOffset
|
||||
let yOffset
|
||||
|
||||
/* We put the thisObject.params.VALUE in the middle */
|
||||
|
||||
fontSize = 22
|
||||
|
||||
browserCanvasContext.font = 'bold ' + fontSize + 'px ' + UI_FONT.PRIMARY
|
||||
|
||||
label = thisObject.params.VALUE
|
||||
if (isNaN(label) === false) {
|
||||
label = Number(label)
|
||||
if (label === 0) { label = label.toFixed(2) } else { label = label.toLocaleString() }
|
||||
}
|
||||
|
||||
label = label.substring(0, 5)
|
||||
|
||||
xOffset = label.length / 2 * fontSize * FONT_ASPECT_RATIO + 7
|
||||
|
||||
labelPoint = {
|
||||
x: centerPoint.x - xOffset,
|
||||
y: centerPoint.y
|
||||
}
|
||||
|
||||
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + OPACITY + ')'
|
||||
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y)
|
||||
|
||||
/* We put the top label */
|
||||
|
||||
fontSize = 12
|
||||
|
||||
browserCanvasContext.font = 'bold ' + fontSize + 'px ' + UI_FONT.PRIMARY
|
||||
|
||||
label = thisObject.params.ASSET_LABEL
|
||||
|
||||
xOffset = label.length / 2 * fontSize * FONT_ASPECT_RATIO + 3
|
||||
yOffset = 22
|
||||
|
||||
labelPoint = {
|
||||
x: centerPoint.x - xOffset,
|
||||
y: centerPoint.y - yOffset
|
||||
}
|
||||
|
||||
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + OPACITY + ')'
|
||||
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y)
|
||||
|
||||
/* We put the bottom label */
|
||||
|
||||
fontSize = 12
|
||||
|
||||
browserCanvasContext.font = 'bold ' + fontSize + 'px ' + UI_FONT.PRIMARY
|
||||
|
||||
label = thisObject.params.ASSET_NAME
|
||||
|
||||
xOffset = label.length / 2 * fontSize * FONT_ASPECT_RATIO + 3
|
||||
yOffset = -15
|
||||
|
||||
labelPoint = {
|
||||
x: centerPoint.x - xOffset,
|
||||
y: centerPoint.y - yOffset
|
||||
}
|
||||
|
||||
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + OPACITY + ')'
|
||||
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ function newCompetitionStorage (pName) {
|
||||
|
||||
case GLOBAL.CUSTOM_FAIL_RESPONSE.result: {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] initialize -> onFileSequenceReady -> Received CUSTOM FAIL Response.') }
|
||||
if (INFO_LOG === true) { logger.write('[INFO] initialize -> onFileSequenceReady -> err.message = ' + err.message) }
|
||||
if (INFO_LOG === true) { logger.write('[INFO] initialize -> onFileSequenceReady -> err= ' + err.stack) }
|
||||
if (INFO_LOG === true) { logger.write('[INFO] initialize -> onFileSequenceReady -> This bot has not starting competing yet.') }
|
||||
|
||||
break
|
||||
|
||||
+120
-6
@@ -1,14 +1,22 @@
|
||||
|
||||
function newContainer () {
|
||||
let thisObject = {
|
||||
id: Math.trunc(Math.random() * 10000000),
|
||||
type: 'Rectangle',
|
||||
frame: undefined,
|
||||
displacement: undefined,
|
||||
eventHandler: undefined,
|
||||
parentContainer: undefined,
|
||||
isDraggeable: true,
|
||||
notDraggingOnX: false,
|
||||
notDraggingOnY: false,
|
||||
isClickeable: false,
|
||||
isWheelable: false,
|
||||
detectMouseOver: false,
|
||||
name: undefined,
|
||||
fitFunction: undefined,
|
||||
isVisibleFunction: undefined,
|
||||
displace: displace,
|
||||
initialize: initialize,
|
||||
finalize: finalize,
|
||||
connectToParent: connectToParent,
|
||||
@@ -17,11 +25,23 @@ function newContainer () {
|
||||
|
||||
let connectedToParentWidth = false
|
||||
let connectedToParentHeight = false
|
||||
let connectedToParentRadius = false
|
||||
|
||||
let onDimmensionsChangedParentEvent = false
|
||||
let onMouseOverParentEvent = false
|
||||
let onMouseNotOverParentEvent = false
|
||||
let onFocusParentEvent = false
|
||||
let onNotFocusParentEvent = false
|
||||
let onDisplaceParentEvent = false
|
||||
|
||||
let isConnectedToParent = false
|
||||
|
||||
let dimensionsChangedEventSubscriptionId
|
||||
let onMouseOverEventSubscriptionId
|
||||
let onMouseNotOverEventSubscriptionId
|
||||
let onFocusEventSubscriptionId
|
||||
let onNotFocusEventSubscriptionId
|
||||
let onDisplaceEventSubscriptionId
|
||||
|
||||
return thisObject
|
||||
|
||||
@@ -30,14 +50,21 @@ function newContainer () {
|
||||
thisObject.parentContainer.eventHandler.stopListening(dimensionsChangedEventSubscriptionId)
|
||||
thisObject.parentContainer.eventHandler.stopListening(onMouseOverEventSubscriptionId)
|
||||
thisObject.parentContainer.eventHandler.stopListening(onMouseNotOverEventSubscriptionId)
|
||||
thisObject.parentContainer.eventHandler.stopListening(onFocusEventSubscriptionId)
|
||||
thisObject.parentContainer.eventHandler.stopListening(onNotFocusEventSubscriptionId)
|
||||
thisObject.parentContainer.eventHandler.stopListening(onDisplaceEventSubscriptionId)
|
||||
|
||||
thisObject.parentContainer = undefined
|
||||
thisObject.eventHandler.finalize()
|
||||
}
|
||||
}
|
||||
|
||||
function initialize (pName) {
|
||||
function initialize (pName, pType) {
|
||||
thisObject.name = pName
|
||||
thisObject.type = pType
|
||||
|
||||
thisObject.frame = newFrame()
|
||||
thisObject.frame.initialize()
|
||||
thisObject.frame.initialize(pType)
|
||||
thisObject.frame.containerName = pName
|
||||
thisObject.frame.container = thisObject
|
||||
|
||||
@@ -49,18 +76,53 @@ function newContainer () {
|
||||
thisObject.displacement.containerName = pName
|
||||
}
|
||||
|
||||
function connectToParent (parentContainer, onWidth, onHeight) {
|
||||
function connectToParent (
|
||||
parentContainer,
|
||||
onWidth,
|
||||
onHeight,
|
||||
onRadius,
|
||||
onDimmensionsChangedEvent,
|
||||
onMouseOverEvent,
|
||||
onMouseNotOverEvent,
|
||||
onFocusEvent,
|
||||
onNotFocusEvent,
|
||||
onDisplaceEvent
|
||||
) {
|
||||
connectedToParentWidth = onWidth
|
||||
connectedToParentHeight = onHeight
|
||||
connectedToParentRadius = onRadius
|
||||
|
||||
onDimmensionsChangedParentEvent = onDimmensionsChangedEvent
|
||||
onMouseOverParentEvent = onMouseOverEvent
|
||||
onMouseNotOverParentEvent = onMouseNotOverEvent
|
||||
onFocusParentEvent = onFocusEvent
|
||||
onNotFocusParentEvent = onNotFocusEvent
|
||||
onDisplaceParentEvent = onDisplaceEvent
|
||||
|
||||
isConnectedToParent = true
|
||||
|
||||
thisObject.displacement.parentDisplacement = parentContainer.displacement
|
||||
thisObject.frame.parentFrame = parentContainer.frame
|
||||
thisObject.parentContainer = parentContainer
|
||||
|
||||
dimensionsChangedEventSubscriptionId = thisObject.parentContainer.eventHandler.listenToEvent('Dimmensions Changed', onParentDimmensionsChanged)
|
||||
onMouseOverEventSubscriptionId = thisObject.parentContainer.eventHandler.listenToEvent('onMouseOver', onMouseOver)
|
||||
onMouseNotOverEventSubscriptionId = thisObject.parentContainer.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver)
|
||||
if (onDimmensionsChangedParentEvent === true) {
|
||||
dimensionsChangedEventSubscriptionId = thisObject.parentContainer.eventHandler.listenToEvent('Dimmensions Changed', onParentDimmensionsChanged)
|
||||
}
|
||||
if (onMouseOverParentEvent === true) {
|
||||
onMouseOverEventSubscriptionId = thisObject.parentContainer.eventHandler.listenToEvent('onMouseOver', onMouseOver)
|
||||
}
|
||||
if (onMouseNotOverParentEvent === true) {
|
||||
onMouseNotOverEventSubscriptionId = thisObject.parentContainer.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver)
|
||||
}
|
||||
if (onFocusParentEvent === true) {
|
||||
onFocusEventSubscriptionId = thisObject.parentContainer.eventHandler.listenToEvent('onFocus', onFocus)
|
||||
}
|
||||
if (onNotFocusParentEvent === true) {
|
||||
onNotFocusEventSubscriptionId = thisObject.parentContainer.eventHandler.listenToEvent('onNotFocus', onNotFocus)
|
||||
}
|
||||
if (onDisplaceParentEvent === true) {
|
||||
onDisplaceEventSubscriptionId = thisObject.parentContainer.eventHandler.listenToEvent('onDisplace', onDisplace)
|
||||
}
|
||||
|
||||
if (connectedToParentWidth) {
|
||||
thisObject.frame.width = thisObject.parentContainer.frame.width
|
||||
@@ -68,6 +130,9 @@ function newContainer () {
|
||||
if (connectedToParentHeight) {
|
||||
thisObject.frame.height = thisObject.parentContainer.frame.height
|
||||
}
|
||||
if (connectedToParentRadius) {
|
||||
thisObject.frame.radius = thisObject.parentContainer.frame.radius
|
||||
}
|
||||
}
|
||||
|
||||
function onParentDimmensionsChanged (event) {
|
||||
@@ -80,6 +145,10 @@ function newContainer () {
|
||||
thisObject.frame.height = thisObject.parentContainer.frame.height
|
||||
dimmensionsChanged = true
|
||||
}
|
||||
if (connectedToParentRadius) {
|
||||
thisObject.frame.radius = thisObject.parentContainer.frame.radius
|
||||
dimmensionsChanged = true
|
||||
}
|
||||
|
||||
if (dimmensionsChanged) {
|
||||
thisObject.eventHandler.raiseEvent('Dimmensions Changed', event)
|
||||
@@ -94,6 +163,18 @@ function newContainer () {
|
||||
thisObject.eventHandler.raiseEvent('onMouseNotOver', event)
|
||||
}
|
||||
|
||||
function onFocus (event) {
|
||||
thisObject.eventHandler.raiseEvent('onFocus', event)
|
||||
}
|
||||
|
||||
function onNotFocus (event) {
|
||||
thisObject.eventHandler.raiseEvent('onNotFocus', event)
|
||||
}
|
||||
|
||||
function onDisplace (event) {
|
||||
thisObject.eventHandler.raiseEvent('onDisplace', event)
|
||||
}
|
||||
|
||||
function isForThisPurpose (purpose) {
|
||||
if (purpose !== undefined) {
|
||||
switch (purpose) {
|
||||
@@ -118,4 +199,37 @@ function newContainer () {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
function displace (point) {
|
||||
/* This function will move the container according to the vector received. If it has a visible function will use it
|
||||
to see if the container can be moved there or not. It wont if the center will not be visible.
|
||||
|
||||
Returns true if move was possible, false if not. */
|
||||
|
||||
let checkPoint = {}
|
||||
|
||||
if (thisObject.isVisibleFunction === undefined) {
|
||||
drag()
|
||||
return true
|
||||
} else {
|
||||
checkPoint.x = thisObject.frame.position.x + point.x + thisObject.frame.width / 2
|
||||
checkPoint.y = thisObject.frame.position.y + point.y + thisObject.frame.height / 2
|
||||
let isVisible = thisObject.isVisibleFunction(checkPoint)
|
||||
if (isVisible === true) {
|
||||
drag()
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
function drag () {
|
||||
if (thisObject.notDraggingOnX === false) {
|
||||
thisObject.frame.position.x = thisObject.frame.position.x + point.x
|
||||
}
|
||||
if (thisObject.notDraggingOnY === false) {
|
||||
thisObject.frame.position.y = thisObject.frame.position.y + point.y
|
||||
}
|
||||
thisObject.eventHandler.raiseEvent('onDisplace', event)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
function newSidePanel () {
|
||||
const MODULE_NAME = 'Side Panel'
|
||||
let thisObject = {
|
||||
areas: [],
|
||||
sidePanelTab: undefined,
|
||||
container: undefined,
|
||||
draw: draw,
|
||||
getContainer: getContainer,
|
||||
initialize: initialize
|
||||
}
|
||||
|
||||
let isInitialized = false
|
||||
|
||||
thisObject.container = newContainer()
|
||||
thisObject.container.name = MODULE_NAME
|
||||
thisObject.container.initialize()
|
||||
thisObject.container.isClickeable = true
|
||||
thisObject.container.isDraggeable = false
|
||||
thisObject.container.status = 'hidden'
|
||||
|
||||
resize()
|
||||
return thisObject
|
||||
|
||||
function initialize () {
|
||||
thisObject.sidePanelTab = newSidePanelTab()
|
||||
thisObject.sidePanelTab.container.connectToParent(thisObject.container, false, false)
|
||||
thisObject.sidePanelTab.initialize()
|
||||
|
||||
window.canvasApp.eventHandler.listenToEvent('Browser Resized', resize)
|
||||
isInitialized = true
|
||||
}
|
||||
|
||||
function resize () {
|
||||
thisObject.container.frame.width = SIDE_PANEL_WIDTH
|
||||
thisObject.container.frame.height = browserCanvas.height // - TOP_SPACE_HEIGHT
|
||||
thisObject.container.frame.position.x = -SIDE_PANEL_WIDTH
|
||||
thisObject.container.frame.position.y = 0 // TOP_SPACE_HEIGHT
|
||||
}
|
||||
|
||||
function getContainer (point) {
|
||||
let container
|
||||
|
||||
container = thisObject.sidePanelTab.getContainer(point)
|
||||
if (container !== undefined) { return container }
|
||||
|
||||
if (thisObject.container.frame.isThisPointHere(point, true) === true) {
|
||||
return thisObject.container
|
||||
} else {
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
function draw () {
|
||||
if (isInitialized === false) { return }
|
||||
borders()
|
||||
thisObject.sidePanelTab.draw()
|
||||
|
||||
for (let i = 0; i < thisObject.areas.length; i++) {
|
||||
let area = thisObject.areas[i]
|
||||
area.draw()
|
||||
}
|
||||
}
|
||||
|
||||
function borders () {
|
||||
let point1
|
||||
let point2
|
||||
let point3
|
||||
let point4
|
||||
|
||||
point1 = {
|
||||
x: 0,
|
||||
y: 0
|
||||
}
|
||||
|
||||
point2 = {
|
||||
x: thisObject.container.frame.width,
|
||||
y: 0
|
||||
}
|
||||
|
||||
point3 = {
|
||||
x: thisObject.container.frame.width,
|
||||
y: thisObject.container.frame.height
|
||||
}
|
||||
|
||||
point4 = {
|
||||
x: 0,
|
||||
y: thisObject.container.frame.height
|
||||
}
|
||||
|
||||
point1 = thisObject.container.frame.frameThisPoint(point1)
|
||||
point2 = thisObject.container.frame.frameThisPoint(point2)
|
||||
point3 = thisObject.container.frame.frameThisPoint(point3)
|
||||
point4 = thisObject.container.frame.frameThisPoint(point4)
|
||||
|
||||
browserCanvasContext.setLineDash([0, 0])
|
||||
browserCanvasContext.beginPath()
|
||||
browserCanvasContext.moveTo(point1.x, point1.y)
|
||||
browserCanvasContext.lineTo(point2.x, point2.y)
|
||||
browserCanvasContext.lineTo(point3.x, point3.y)
|
||||
browserCanvasContext.lineTo(point4.x, point4.y)
|
||||
browserCanvasContext.lineTo(point1.x, point1.y)
|
||||
browserCanvasContext.closePath()
|
||||
|
||||
let opacity = 1
|
||||
|
||||
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.LIGHT_GREY + ', ' + opacity + ''
|
||||
browserCanvasContext.fill()
|
||||
|
||||
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.GREY + ', ' + opacity + ''
|
||||
browserCanvasContext.lineWidth = 0.3
|
||||
browserCanvasContext.stroke()
|
||||
|
||||
/* Shadow */
|
||||
|
||||
if (thisObject.container.status !== 'hidden') {
|
||||
for (let i = 0; i <= 30; i++) {
|
||||
opacity = 1 - (i / 300) - 0.95
|
||||
|
||||
browserCanvasContext.setLineDash([0, 0])
|
||||
browserCanvasContext.beginPath()
|
||||
browserCanvasContext.moveTo(point2.x + i, point2.y)
|
||||
browserCanvasContext.lineTo(point3.x + i, point3.y)
|
||||
browserCanvasContext.closePath()
|
||||
|
||||
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.BLACK + ', ' + opacity + ''
|
||||
browserCanvasContext.lineWidth = 1
|
||||
browserCanvasContext.stroke()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,216 @@
|
||||
function newSidePanelTab () {
|
||||
const MODULE_NAME = 'Side Panel Tab'
|
||||
let thisObject = {
|
||||
pointerDirection: 'left',
|
||||
container: undefined,
|
||||
draw: draw,
|
||||
getContainer: getContainer,
|
||||
initialize: initialize
|
||||
}
|
||||
|
||||
const TAB_WIDTH = 25
|
||||
const TAB_HEIGHT = 60
|
||||
|
||||
let isInitialized = false
|
||||
let animation = 'none'
|
||||
let ORIGINAL_PARENT_POSITON
|
||||
let xOffset = 0
|
||||
|
||||
thisObject.container = newContainer()
|
||||
thisObject.container.name = MODULE_NAME
|
||||
thisObject.container.initialize()
|
||||
thisObject.container.isClickeable = true
|
||||
thisObject.container.isDraggeable = false
|
||||
|
||||
return thisObject
|
||||
|
||||
function initialize () {
|
||||
thisObject.container.frame.width = TAB_WIDTH
|
||||
thisObject.container.frame.height = TAB_HEIGHT
|
||||
thisObject.container.frame.position.x = 0 + thisObject.container.parentContainer.frame.width
|
||||
thisObject.container.frame.position.y = 20
|
||||
|
||||
ORIGINAL_PARENT_POSITON = thisObject.container.parentContainer.frame.position.x
|
||||
|
||||
thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick)
|
||||
isInitialized = true
|
||||
}
|
||||
|
||||
function onMouseClick (event) {
|
||||
if (thisObject.pointerDirection === 'left') {
|
||||
animation = 'opening'
|
||||
} else {
|
||||
animation = 'closing'
|
||||
}
|
||||
}
|
||||
|
||||
function getContainer (point) {
|
||||
let container
|
||||
if (thisObject.container.frame.isThisPointHere(point, true) === true) {
|
||||
return thisObject.container
|
||||
} else {
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
function draw () {
|
||||
if (isInitialized === false) { return }
|
||||
animate()
|
||||
borders()
|
||||
arrow()
|
||||
}
|
||||
|
||||
function animate () {
|
||||
const STEP = 50
|
||||
|
||||
if (animation === 'opening') {
|
||||
xOffset = xOffset + STEP
|
||||
thisObject.container.parentContainer.frame.position.x = ORIGINAL_PARENT_POSITON + xOffset
|
||||
if (xOffset > thisObject.container.parentContainer.frame.width) {
|
||||
animation = 'none'
|
||||
xOffset = thisObject.container.parentContainer.frame.width
|
||||
thisObject.container.parentContainer.frame.position.x = ORIGINAL_PARENT_POSITON + xOffset
|
||||
thisObject.container.parentContainer.status = 'visible'
|
||||
thisObject.pointerDirection = 'right'
|
||||
}
|
||||
}
|
||||
|
||||
if (animation === 'closing') {
|
||||
xOffset = xOffset - STEP
|
||||
thisObject.container.parentContainer.frame.position.x = ORIGINAL_PARENT_POSITON + xOffset
|
||||
if (xOffset < 0) {
|
||||
animation = 'none'
|
||||
xOffset = 0
|
||||
thisObject.container.parentContainer.frame.position.x = ORIGINAL_PARENT_POSITON
|
||||
thisObject.container.parentContainer.status = 'hidden'
|
||||
thisObject.pointerDirection = 'left'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function arrow () {
|
||||
let point1
|
||||
let point2
|
||||
let point3
|
||||
|
||||
if (thisObject.pointerDirection === 'left') {
|
||||
point1 = {
|
||||
x: TAB_WIDTH * 3.5 / 10,
|
||||
y: TAB_HEIGHT * 12.5 / 30
|
||||
}
|
||||
|
||||
point2 = {
|
||||
x: TAB_WIDTH * 6.5 / 10,
|
||||
y: TAB_HEIGHT * 15 / 30
|
||||
}
|
||||
|
||||
point3 = {
|
||||
x: TAB_WIDTH * 3.5 / 10,
|
||||
y: TAB_HEIGHT * 17.5 / 30
|
||||
}
|
||||
} else {
|
||||
point1 = {
|
||||
x: TAB_WIDTH * 6.5 / 10,
|
||||
y: TAB_HEIGHT * 12.5 / 30
|
||||
}
|
||||
|
||||
point2 = {
|
||||
x: TAB_WIDTH * 3.5 / 10,
|
||||
y: TAB_HEIGHT * 15 / 30
|
||||
}
|
||||
|
||||
point3 = {
|
||||
x: TAB_WIDTH * 6.5 / 10,
|
||||
y: TAB_HEIGHT * 17.5 / 30
|
||||
}
|
||||
}
|
||||
|
||||
point1 = thisObject.container.frame.frameThisPoint(point1)
|
||||
point2 = thisObject.container.frame.frameThisPoint(point2)
|
||||
point3 = thisObject.container.frame.frameThisPoint(point3)
|
||||
|
||||
browserCanvasContext.beginPath()
|
||||
browserCanvasContext.moveTo(point1.x, point1.y)
|
||||
browserCanvasContext.lineTo(point2.x, point2.y)
|
||||
browserCanvasContext.lineTo(point3.x, point3.y)
|
||||
browserCanvasContext.closePath()
|
||||
|
||||
let opacity = 1
|
||||
|
||||
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.GREY + ', ' + opacity + ''
|
||||
browserCanvasContext.fill()
|
||||
}
|
||||
|
||||
function borders () {
|
||||
let point1
|
||||
let point2
|
||||
let point3
|
||||
let point4
|
||||
|
||||
point1 = {
|
||||
x: 0,
|
||||
y: 0
|
||||
}
|
||||
|
||||
point2 = {
|
||||
x: TAB_WIDTH,
|
||||
y: 0
|
||||
}
|
||||
|
||||
point3 = {
|
||||
x: TAB_WIDTH,
|
||||
y: TAB_HEIGHT
|
||||
}
|
||||
|
||||
point4 = {
|
||||
x: 0,
|
||||
y: TAB_HEIGHT
|
||||
}
|
||||
|
||||
point1 = thisObject.container.frame.frameThisPoint(point1)
|
||||
point2 = thisObject.container.frame.frameThisPoint(point2)
|
||||
point3 = thisObject.container.frame.frameThisPoint(point3)
|
||||
point4 = thisObject.container.frame.frameThisPoint(point4)
|
||||
|
||||
let opacity
|
||||
|
||||
/* Shadow */
|
||||
|
||||
for (let i = 0; i <= 5; i++) {
|
||||
opacity = 1 - (i / 100) - 0.93
|
||||
|
||||
browserCanvasContext.beginPath()
|
||||
browserCanvasContext.moveTo(point1.x + i, point1.y + i)
|
||||
browserCanvasContext.lineTo(point2.x + i, point2.y + i)
|
||||
browserCanvasContext.lineTo(point3.x + i, point3.y + i)
|
||||
browserCanvasContext.lineTo(point4.x + i, point4.y + i)
|
||||
browserCanvasContext.lineTo(point1.x + i, point1.y + i)
|
||||
browserCanvasContext.closePath()
|
||||
|
||||
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.BLACK + ', ' + opacity + ''
|
||||
browserCanvasContext.lineWidth = 1
|
||||
browserCanvasContext.stroke()
|
||||
}
|
||||
|
||||
/* Background and Border */
|
||||
|
||||
browserCanvasContext.setLineDash([0, 0])
|
||||
browserCanvasContext.beginPath()
|
||||
browserCanvasContext.moveTo(point1.x, point1.y)
|
||||
browserCanvasContext.lineTo(point2.x, point2.y)
|
||||
browserCanvasContext.lineTo(point3.x, point3.y)
|
||||
browserCanvasContext.lineTo(point4.x, point4.y)
|
||||
browserCanvasContext.lineTo(point1.x, point1.y)
|
||||
browserCanvasContext.closePath()
|
||||
|
||||
opacity = 1
|
||||
|
||||
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + opacity + ''
|
||||
browserCanvasContext.fill()
|
||||
|
||||
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.GREY + ', ' + opacity + ''
|
||||
browserCanvasContext.lineWidth = 0.3
|
||||
browserCanvasContext.stroke()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ let viewPort = newViewPort()
|
||||
|
||||
function newDashboard () {
|
||||
const MODULE_NAME = 'Dashboard'
|
||||
const INFO_LOG = false
|
||||
const ERROR_LOG = true
|
||||
const INTENSIVE_LOG = false
|
||||
const logger = newWebDebugLog()
|
||||
@@ -25,8 +24,6 @@ function newDashboard () {
|
||||
|
||||
function start () {
|
||||
try {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] start -> Entering function.') }
|
||||
|
||||
/* If this method is executed for a second time, it should finalize the current execution structure */
|
||||
|
||||
if (canvas !== undefined) { canvas.finalize() }
|
||||
@@ -40,8 +37,6 @@ function newDashboard () {
|
||||
loadImages(onImagesLoaded)
|
||||
|
||||
function onImagesLoaded () {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] start -> onImagesLoaded -> Entering function.') }
|
||||
|
||||
/* Next we start the App */
|
||||
|
||||
setTimeout(delayedStart, DEBUG_START_UP_DELAY)
|
||||
@@ -53,8 +48,6 @@ function newDashboard () {
|
||||
|
||||
function delayedStart () {
|
||||
try {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] delayedStart -> Entering function.') }
|
||||
|
||||
/* For now, we are supporting only one market. */
|
||||
|
||||
let market = {
|
||||
@@ -76,8 +69,6 @@ function newDashboard () {
|
||||
|
||||
function userProfileChanged () {
|
||||
try {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] userProfileChanged -> Entering function.') }
|
||||
|
||||
canvas.topSpace.initialize()
|
||||
} catch (err) {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] userProfileChanged -> err = ' + err.stack) }
|
||||
@@ -86,8 +77,6 @@ function newDashboard () {
|
||||
|
||||
function browserResized () {
|
||||
try {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] browserResized -> Entering function.') }
|
||||
|
||||
browserCanvas = document.getElementById('canvas')
|
||||
|
||||
browserCanvas.width = window.innerWidth
|
||||
@@ -101,8 +90,6 @@ function newDashboard () {
|
||||
|
||||
function loadImages (callBack) {
|
||||
try {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] loadImages -> Entering function.') }
|
||||
|
||||
const accessToken = ''
|
||||
|
||||
/*
|
||||
|
||||
+7
-2
@@ -4,13 +4,18 @@ function newEventHandler () {
|
||||
name: undefined, // This is for debugging purposes only.
|
||||
listenToEvent: listenToEvent,
|
||||
stopListening: stopListening,
|
||||
raiseEvent: raiseEvent
|
||||
raiseEvent: raiseEvent,
|
||||
finalize: finalize
|
||||
}
|
||||
|
||||
var eventHandlers = [] // Here we store all the functions we will call when an event is raiseed.
|
||||
let eventHandlers = [] // Here we store all the functions we will call when an event is raiseed.
|
||||
|
||||
return thisObject
|
||||
|
||||
function finalize () {
|
||||
eventHandlers = []
|
||||
}
|
||||
|
||||
function listenToEvent (eventType, handler, extraData) {
|
||||
let eventSubscriptionId = Math.trunc(Math.random() * 1000000)
|
||||
eventHandlers.push([eventType, handler, extraData, eventSubscriptionId])
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
|
||||
function newCircularMenu () {
|
||||
const MODULE_NAME = 'Circular Menu'
|
||||
|
||||
let thisObject = {
|
||||
container: undefined,
|
||||
isDeployed: undefined,
|
||||
physics: physics,
|
||||
drawBackground: drawBackground,
|
||||
drawForeground: drawForeground,
|
||||
getContainer: getContainer,
|
||||
finalize: finalize,
|
||||
initialize: initialize
|
||||
}
|
||||
|
||||
thisObject.container = newContainer()
|
||||
thisObject.container.initialize(MODULE_NAME, 'Circle')
|
||||
thisObject.container.isClickeable = false
|
||||
thisObject.container.isDraggeable = false
|
||||
thisObject.container.frame.radius = 0
|
||||
thisObject.container.frame.position.x = 0
|
||||
thisObject.container.frame.position.y = 0
|
||||
|
||||
let menuItems = []
|
||||
|
||||
let selfFocusEventSubscriptionId
|
||||
let selfNotFocuskEventSubscriptionId
|
||||
|
||||
return thisObject
|
||||
|
||||
function finalize () {
|
||||
thisObject.container.eventHandler.stopListening(selfFocusEventSubscriptionId)
|
||||
thisObject.container.eventHandler.stopListening(selfNotFocuskEventSubscriptionId)
|
||||
|
||||
thisObject.container.finalize()
|
||||
thisObject.container = undefined
|
||||
|
||||
for (let i = 0; i < menuItems.length; i++) {
|
||||
let menuItem = menuItems[i]
|
||||
menuItem.finalize()
|
||||
}
|
||||
|
||||
menuItems = undefined
|
||||
}
|
||||
|
||||
function initialize (menuItemsInitialValues, payload) {
|
||||
/* Create the array of Menu Items */
|
||||
|
||||
for (let i = 0; i < menuItemsInitialValues.length; i++) {
|
||||
let menuItem = newCircularMenuItem()
|
||||
let menuItemInitialValue = menuItemsInitialValues[i]
|
||||
|
||||
menuItem.action = menuItemInitialValue.action
|
||||
menuItem.actionFunction = menuItemInitialValue.actionFunction
|
||||
menuItem.label = menuItemInitialValue.label
|
||||
menuItem.workingLabel = menuItemInitialValue.workingLabel
|
||||
menuItem.workDoneLabel = menuItemInitialValue.workDoneLabel
|
||||
menuItem.workFailedLabel = menuItemInitialValue.workFailedLabel
|
||||
menuItem.visible = menuItemInitialValue.visible
|
||||
menuItem.iconPathOn = menuItemInitialValue.iconPathOn
|
||||
menuItem.iconPathOff = menuItemInitialValue.iconPathOff
|
||||
menuItem.rawRadius = menuItemInitialValue.rawRadius
|
||||
menuItem.targetRadius = menuItemInitialValue.label
|
||||
menuItem.currentRadius = menuItemInitialValue.currentRadius
|
||||
menuItem.angle = menuItemInitialValue.angle
|
||||
menuItem.currentStatus = menuItemInitialValue.currentStatus
|
||||
menuItem.relatedStrategyPart = menuItemInitialValue.relatedStrategyPart
|
||||
|
||||
if (menuItem.label === undefined) {
|
||||
menuItem.type = 'Icon Only'
|
||||
} else {
|
||||
menuItem.type = 'Icon & Text'
|
||||
}
|
||||
|
||||
menuItem.initialize(payload)
|
||||
menuItem.container.connectToParent(thisObject.container, false, false, true, true, false, false, true, true)
|
||||
menuItems.push(menuItem)
|
||||
}
|
||||
|
||||
selfFocusEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onFocus', onFocus)
|
||||
selfNotFocuskEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onNotFocus', onNotFocus)
|
||||
}
|
||||
|
||||
function getContainer (point) {
|
||||
let container
|
||||
|
||||
if (thisObject.isDeployed === true) {
|
||||
for (let i = 0; i < menuItems.length; i++) {
|
||||
let menutItem = menuItems[i]
|
||||
container = menutItem.getContainer(point)
|
||||
if (container !== undefined) { return container }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function physics () {
|
||||
for (let i = 0; i < menuItems.length; i++) {
|
||||
let menutItem = menuItems[i]
|
||||
menutItem.physics()
|
||||
}
|
||||
}
|
||||
|
||||
function onFocus () {
|
||||
for (let i = 0; i < menuItems.length; i++) {
|
||||
let menutItem = menuItems[i]
|
||||
menutItem.targetRadius = menutItem.rawRadius * 1.5
|
||||
menutItem.isDeployed = true
|
||||
}
|
||||
thisObject.isDeployed = true
|
||||
}
|
||||
|
||||
function onNotFocus () {
|
||||
for (let i = 0; i < menuItems.length; i++) {
|
||||
let menutItem = menuItems[i]
|
||||
menutItem.targetRadius = menutItem.rawRadius * 0 - i * 5
|
||||
menutItem.isDeployed = false
|
||||
}
|
||||
thisObject.isDeployed = false
|
||||
}
|
||||
|
||||
function drawBackground (pFloatingObject) {
|
||||
for (let i = 0; i < menuItems.length; i++) {
|
||||
let menutItem = menuItems[i]
|
||||
menutItem.drawBackground()
|
||||
}
|
||||
}
|
||||
|
||||
function drawForeground (pFloatingObject) {
|
||||
for (let i = 0; i < menuItems.length; i++) {
|
||||
let menutItem = menuItems[i]
|
||||
menutItem.drawForeground()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,249 @@
|
||||
|
||||
function newCircularMenuItem () {
|
||||
const MODULE_NAME = 'Circular Menu Iem'
|
||||
|
||||
let thisObject = {
|
||||
type: undefined,
|
||||
isDeployed: undefined,
|
||||
iconOn: undefined,
|
||||
iconOff: undefined,
|
||||
currentIcon: undefined,
|
||||
action: undefined,
|
||||
actionFunction: undefined,
|
||||
label: undefined,
|
||||
workingLabel: undefined,
|
||||
workDoneLabel: undefined,
|
||||
workFailedLabel: undefined,
|
||||
visible: false,
|
||||
iconPathOn: undefined,
|
||||
iconPathOff: undefined,
|
||||
rawRadius: undefined,
|
||||
targetRadius: undefined,
|
||||
currentRadius: undefined,
|
||||
angle: undefined,
|
||||
container: undefined,
|
||||
payload: undefined,
|
||||
relatedStrategyPart: undefined,
|
||||
physics: physics,
|
||||
drawBackground: drawBackground,
|
||||
drawForeground: drawForeground,
|
||||
getContainer: getContainer,
|
||||
finalize: finalize,
|
||||
initialize: initialize
|
||||
}
|
||||
|
||||
thisObject.container = newContainer()
|
||||
thisObject.container.initialize(MODULE_NAME)
|
||||
thisObject.container.isClickeable = true
|
||||
thisObject.container.isDraggeable = false
|
||||
thisObject.container.detectMouseOver = true
|
||||
thisObject.container.frame.radius = 0
|
||||
thisObject.container.frame.position.x = 0
|
||||
thisObject.container.frame.position.y = 0
|
||||
thisObject.container.frame.width = 0
|
||||
thisObject.container.frame.height = 30
|
||||
|
||||
let isMouseOver = false
|
||||
|
||||
let selfMouseOverEventSubscriptionId
|
||||
let selfMouseClickEventSubscriptionId
|
||||
let selfMouseNotOverEventSubscriptionId
|
||||
|
||||
let labelToPrint = ''
|
||||
let defaultBackgroudColor = UI_COLOR.RED
|
||||
let backgroundColorToUse = UI_COLOR.RED
|
||||
let temporaryStatus = 0
|
||||
|
||||
const EXTRA_MOUSE_OVER_ICON_SIZE = 2
|
||||
return thisObject
|
||||
|
||||
function finalize () {
|
||||
thisObject.container.eventHandler.stopListening(selfMouseOverEventSubscriptionId)
|
||||
thisObject.container.eventHandler.stopListening(selfMouseClickEventSubscriptionId)
|
||||
thisObject.container.eventHandler.stopListening(selfMouseNotOverEventSubscriptionId)
|
||||
|
||||
thisObject.container.finalize()
|
||||
thisObject.container = undefined
|
||||
thisObject.iconOn = undefined
|
||||
thisObject.iconOff = undefined
|
||||
thisObject.currentIcon = undefined
|
||||
thisObject.payload = undefined
|
||||
thisObject.actionFunction = undefined
|
||||
}
|
||||
|
||||
function initialize (pPayload) {
|
||||
thisObject.payload = pPayload
|
||||
|
||||
iconPhysics()
|
||||
|
||||
selfMouseOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver)
|
||||
selfMouseClickEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick)
|
||||
selfMouseNotOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver)
|
||||
|
||||
if (thisObject.type === 'Icon & Text') {
|
||||
thisObject.container.frame.width = 150
|
||||
} else {
|
||||
thisObject.container.frame.width = 50
|
||||
}
|
||||
}
|
||||
|
||||
function getContainer (point) {
|
||||
let container
|
||||
if (thisObject.isDeployed === true) {
|
||||
if (thisObject.container.frame.isThisPointHere(point, true, false) === true) {
|
||||
return thisObject.container
|
||||
} else {
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function physics () {
|
||||
const INCREASE_STEP = 0.25
|
||||
|
||||
if (Math.abs(thisObject.currentRadius - thisObject.targetRadius) >= INCREASE_STEP) {
|
||||
if (thisObject.currentRadius < thisObject.targetRadius) {
|
||||
thisObject.currentRadius = thisObject.currentRadius + INCREASE_STEP
|
||||
} else {
|
||||
thisObject.currentRadius = thisObject.currentRadius - INCREASE_STEP
|
||||
}
|
||||
}
|
||||
|
||||
thisObject.container.frame.position.x = thisObject.container.frame.radius * 3 / 7 * Math.cos(toRadians(thisObject.angle)) - thisObject.currentRadius * 1.5
|
||||
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 */
|
||||
|
||||
temporaryStatus--
|
||||
if (temporaryStatus < 0) {
|
||||
temporaryStatus = 0
|
||||
}
|
||||
if (temporaryStatus === 0) {
|
||||
labelToPrint = thisObject.label
|
||||
backgroundColorToUse = defaultBackgroudColor
|
||||
}
|
||||
|
||||
iconPhysics()
|
||||
}
|
||||
|
||||
function iconPhysics () {
|
||||
if (thisObject.relatedStrategyPart !== undefined) {
|
||||
thisObject.iconOn = canvas.strategySpace.iconByPartType.get(thisObject.relatedStrategyPart)
|
||||
thisObject.iconOff = canvas.strategySpace.iconByPartType.get(thisObject.relatedStrategyPart)
|
||||
} else {
|
||||
thisObject.iconOn = canvas.strategySpace.iconCollection.get(thisObject.iconPathOn)
|
||||
thisObject.iconOff = canvas.strategySpace.iconCollection.get(thisObject.iconPathOff)
|
||||
}
|
||||
|
||||
/* Current Status sets the icon to be used */
|
||||
|
||||
if (thisObject.currentStatus === true) {
|
||||
thisObject.icon = thisObject.iconOn
|
||||
} else {
|
||||
thisObject.icon = thisObject.iconOff
|
||||
}
|
||||
}
|
||||
|
||||
function onMouseOver (point) {
|
||||
if (thisObject.container.frame.isThisPointHere(point, true, false) === true) {
|
||||
isMouseOver = true
|
||||
} else {
|
||||
isMouseOver = false
|
||||
}
|
||||
}
|
||||
|
||||
function onMouseNotOver (point) {
|
||||
isMouseOver = false
|
||||
}
|
||||
|
||||
async function onMouseClick (event) {
|
||||
if (temporaryStatus === 0) {
|
||||
if (thisObject.workingLabel !== undefined) {
|
||||
setTemporaryStatus(thisObject.workingLabel, UI_COLOR.GREY, 500)
|
||||
}
|
||||
|
||||
thisObject.currentStatus = await thisObject.actionFunction(thisObject.payload, thisObject.action)
|
||||
|
||||
if (thisObject.currentStatus === true) {
|
||||
if (thisObject.workDoneLabel !== undefined) {
|
||||
setTemporaryStatus(thisObject.workDoneLabel, UI_COLOR.PATINATED_TURQUOISE, 250)
|
||||
}
|
||||
} else {
|
||||
if (thisObject.workFailedLabel != undefined) {
|
||||
setTemporaryStatus(thisObject.workFailedLabel, UI_COLOR.TITANIUM_YELLOW, 500)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setTemporaryStatus (text, backgroundColor, waitingCycles) {
|
||||
labelToPrint = text
|
||||
backgroundColorToUse = backgroundColor
|
||||
temporaryStatus = waitingCycles
|
||||
}
|
||||
|
||||
function drawBackground () {
|
||||
if (thisObject.container.frame.position.x > 0 && thisObject.isDeployed === true && thisObject.currentRadius >= thisObject.targetRadius) {
|
||||
if (thisObject.type === 'Icon & Text') {
|
||||
let params = {
|
||||
cornerRadius: 3,
|
||||
lineWidth: 0.1,
|
||||
container: thisObject.container,
|
||||
borderColor: UI_COLOR.DARK,
|
||||
backgroundColor: backgroundColorToUse,
|
||||
castShadow: false
|
||||
}
|
||||
|
||||
if (isMouseOver === true) {
|
||||
params.opacity = 1
|
||||
} else {
|
||||
params.opacity = 0.8
|
||||
}
|
||||
|
||||
roundedCornersBackground(params)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function drawForeground () {
|
||||
let menuPosition = {
|
||||
x: thisObject.currentRadius * 1.5,
|
||||
y: thisObject.container.frame.height / 2
|
||||
}
|
||||
|
||||
menuPosition = thisObject.container.frame.frameThisPoint(menuPosition)
|
||||
|
||||
/* Menu Item */
|
||||
|
||||
let iconSize
|
||||
if (isMouseOver === true) {
|
||||
iconSize = thisObject.currentRadius + EXTRA_MOUSE_OVER_ICON_SIZE
|
||||
} else {
|
||||
iconSize = thisObject.currentRadius
|
||||
}
|
||||
|
||||
if (thisObject.icon.canDrawIcon === true && thisObject.currentRadius > 1 && thisObject.isDeployed === true) {
|
||||
browserCanvasContext.drawImage(thisObject.icon, menuPosition.x - iconSize, menuPosition.y - iconSize, iconSize * 2, iconSize * 2)
|
||||
|
||||
/* Menu Label */
|
||||
|
||||
if (thisObject.type === 'Icon & Text') {
|
||||
let labelPoint
|
||||
let fontSize = 10
|
||||
|
||||
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
|
||||
|
||||
if (thisObject.currentRadius >= thisObject.targetRadius) {
|
||||
labelPoint = {
|
||||
x: menuPosition.x + thisObject.currentRadius + 10,
|
||||
y: menuPosition.y + fontSize * FONT_ASPECT_RATIO
|
||||
}
|
||||
|
||||
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
|
||||
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', 1)'
|
||||
browserCanvasContext.fillText(labelToPrint, labelPoint.x, labelPoint.y)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,215 @@
|
||||
|
||||
function newCodeEditor () {
|
||||
const MODULE_NAME = 'Circular Menu Iem'
|
||||
|
||||
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
|
||||
|
||||
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(204, 88, 53);' +
|
||||
'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
|
||||
thisObject.container.frame.height = thisObject.container.frame.radius * 1
|
||||
|
||||
let textAreaPosition = {
|
||||
x: 0 - thisObject.container.frame.width / 2,
|
||||
y: 0 + thisObject.container.frame.height * 2 / 7
|
||||
}
|
||||
|
||||
textAreaPosition = thisObject.container.frame.frameThisPoint(textAreaPosition)
|
||||
if (thisObject.visible === true) {
|
||||
let checkPosition = {
|
||||
x: textAreaPosition.x,
|
||||
y: textAreaPosition.y - window.canvasApp.topMargin
|
||||
}
|
||||
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
|
||||
|
||||
if (radius > 0.5) {
|
||||
browserCanvasContext.beginPath()
|
||||
browserCanvasContext.arc(position.x, position.y, radius * 1.3 + 3, 0, Math.PI * 2, true)
|
||||
browserCanvasContext.closePath()
|
||||
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + 1 + ')'
|
||||
browserCanvasContext.fill()
|
||||
|
||||
browserCanvasContext.beginPath()
|
||||
browserCanvasContext.arc(position.x, position.y, radius * 1.3, 0, Math.PI * 2, true)
|
||||
browserCanvasContext.closePath()
|
||||
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.RUSTED_RED + ', ' + 1 + ')'
|
||||
browserCanvasContext.fill()
|
||||
}
|
||||
}
|
||||
}
|
||||
function drawForeground () {
|
||||
let iconPosition = {
|
||||
x: 0,
|
||||
y: thisObject.currentRadius * 1.5
|
||||
}
|
||||
|
||||
iconPosition = thisObject.container.frame.frameThisPoint(iconPosition)
|
||||
|
||||
/* Menu Item */
|
||||
|
||||
if (thisObject.canDrawIcon === true && thisObject.currentRadius > 1) {
|
||||
browserCanvasContext.drawImage(thisObject.icon, iconPosition.x - thisObject.currentRadius, iconPosition.y - thisObject.currentRadius, thisObject.currentRadius * 2, thisObject.currentRadius * 2)
|
||||
|
||||
/* Menu Label */
|
||||
|
||||
let label = 'Code looks good!'
|
||||
let labelPoint
|
||||
let fontSize = 10
|
||||
|
||||
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
|
||||
|
||||
if (label !== undefined && thisObject.currentRadius >= thisObject.targetRadius) {
|
||||
labelPoint = {
|
||||
x: iconPosition.x + thisObject.currentRadius + 10,
|
||||
y: iconPosition.y + fontSize * FONT_ASPECT_RATIO
|
||||
}
|
||||
|
||||
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
|
||||
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', 1)'
|
||||
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+274
-522
File diff suppressed because it is too large.
Load diff
+172
-103
@@ -1,155 +1,221 @@
|
||||
|
||||
|
||||
function newFloatingObject () {
|
||||
const MODULE_NAME = 'Floating Object'
|
||||
const INFO_LOG = false
|
||||
const INTENSIVE_LOG = false
|
||||
const ERROR_LOG = true
|
||||
|
||||
const logger = newWebDebugLog()
|
||||
logger.fileName = MODULE_NAME
|
||||
|
||||
let thisObject = {
|
||||
|
||||
physicsLoop: physicsLoop,
|
||||
eventHandler: undefined,
|
||||
|
||||
fitFunction: undefined,
|
||||
container: undefined,
|
||||
positionLocked: false,
|
||||
isOnFocus: false,
|
||||
payload: undefined, // This is a reference to an object controlled by a Plotter. The plotter can change its internal value and we will see them from here.
|
||||
type: undefined, // Currently there are two types of Floating Objects: Profile Balls, and Notes.
|
||||
|
||||
physicsEnabled: false,
|
||||
|
||||
currentSpeed: 0, // This is the current speed of the floating object.
|
||||
currentMass: 0, // This is the current mass of the floating object, including its zoom applied.
|
||||
friction: 0, // This is a factor that will ultimatelly desacelerate the floating object.
|
||||
rawMass: 0, // This is the mass value without zoom.
|
||||
rawRadius: 0, // This is the radius of this floating object without zoom.
|
||||
targetRadius: 0, // This is the target radius of the floating object with zoom applied. It should be animated until reaching this value.
|
||||
isPinned: false,
|
||||
pinToggle: pinToggle,
|
||||
physics: physics,
|
||||
initializeMass: initializeMass,
|
||||
initializeRadius: initializeRadius,
|
||||
initializeImageSize: initializeImageSize,
|
||||
initializeFontSize: initializeFontSize,
|
||||
|
||||
imageId: undefined,
|
||||
|
||||
currentPosition: 0, // Current x,y position of the floating object at the floating object's layer, where there is no displacement or zoom. This position is always changing towards the target position.
|
||||
currentSpeed: 0, // This is the current speed of the floating object.
|
||||
currentRadius: 0, // This is the current radius of the floating object, including its zoom applied.
|
||||
currentMass: 0, // This is the current mass of the floating object, including its zoom applied.
|
||||
|
||||
friction: 0, // This is a factor that will ultimatelly desacelerate the floating object.
|
||||
|
||||
rawMass: 0, // This is the mass value without zoom.
|
||||
rawRadius: 0, // This is the radius of this floating object without zoom.
|
||||
|
||||
targetRadius: 0, // This is the target radius of the floating object with zoom applied. It should be animated until reaching this value.
|
||||
|
||||
fillStyle: '',
|
||||
|
||||
labelStrokeStyle: '',
|
||||
|
||||
radomizeCurrentPosition: radomizeCurrentPosition,
|
||||
radomizeCurrentSpeed: radomizeCurrentSpeed,
|
||||
|
||||
drawBackground: drawBackground,
|
||||
drawMiddleground: drawMiddleground,
|
||||
drawForeground: drawForeground,
|
||||
|
||||
drawOnFocus: drawOnFocus,
|
||||
updateMass: updateMass, // Function to update the mass when the zoom level changed.
|
||||
updateRadius: updateRadius, // Function to update the radius when the zoom level changed.
|
||||
|
||||
linkedObject: undefined, // This is a reference to the object that this floating object is representing.
|
||||
linkedObjectType: '', // Since there might be floating objects for different types of objects, here we store the type of object we are linking to.
|
||||
|
||||
container: undefined, // This is a pointer to the object where the floating object belongs to.
|
||||
getContainer: getContainer,
|
||||
finalize: finalize,
|
||||
initialize: initialize
|
||||
|
||||
}
|
||||
|
||||
let underlayingObject
|
||||
thisObject.container = newContainer()
|
||||
thisObject.container.initialize(MODULE_NAME, 'Circle')
|
||||
thisObject.container.isClickeable = true
|
||||
thisObject.container.isDraggeable = true
|
||||
thisObject.container.detectMouseOver = true
|
||||
thisObject.container.frame.radius = 0
|
||||
thisObject.container.frame.position.x = 0
|
||||
thisObject.container.frame.position.y = 0
|
||||
|
||||
thisObject.eventHandler = newEventHandler()
|
||||
let selfMouseOverEventSubscriptionId
|
||||
let selfMouseClickEventSubscriptionId
|
||||
let spaceMouseOverEventSubscriptionId
|
||||
let spaceFocusAquiredEventSubscriptionId
|
||||
|
||||
return thisObject
|
||||
|
||||
function initialize (pType, callBackFunction) {
|
||||
try {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] initialize -> Entering function.') }
|
||||
function finalize () {
|
||||
thisObject.container.eventHandler.stopListening(selfMouseOverEventSubscriptionId)
|
||||
thisObject.container.eventHandler.stopListening(selfMouseClickEventSubscriptionId)
|
||||
canvas.floatingSpace.container.eventHandler.stopListening(spaceMouseOverEventSubscriptionId)
|
||||
canvas.floatingSpace.container.eventHandler.stopListening(spaceFocusAquiredEventSubscriptionId)
|
||||
|
||||
switch (pType) {
|
||||
thisObject.container.finalize()
|
||||
thisObject.container = undefined
|
||||
thisObject.payload = undefined
|
||||
thisObject.fitFunction = undefined
|
||||
}
|
||||
|
||||
case 'Profile Ball': {
|
||||
underlayingObject = newProfileBall()
|
||||
underlayingObject.initialize(onInitialized)
|
||||
function initialize (type, payload) {
|
||||
thisObject.payload = payload
|
||||
thisObject.type = type
|
||||
|
||||
function onInitialized (err) {
|
||||
selfMouseOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver)
|
||||
selfMouseClickEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick)
|
||||
|
||||
}
|
||||
/* To consider that this object lost the focus, we monitor the space for 2 key events */
|
||||
spaceMouseOverEventSubscriptionId = canvas.floatingSpace.container.eventHandler.listenToEvent('onMouseOver', mouseOverFlotingSpace)
|
||||
spaceFocusAquiredEventSubscriptionId = canvas.floatingSpace.container.eventHandler.listenToEvent('onFocusAquired', someoneAquiredFocus)
|
||||
|
||||
break
|
||||
}
|
||||
case 'Note': {
|
||||
underlayingObject = newNote()
|
||||
underlayingObject.initialize(onInitialized)
|
||||
/* Assign a position and speed */
|
||||
|
||||
function onInitialized (err) {
|
||||
thisObject.radomizeCurrentPosition(thisObject.payload.targetPosition)
|
||||
thisObject.radomizeCurrentSpeed()
|
||||
}
|
||||
|
||||
}
|
||||
break
|
||||
}
|
||||
default: {
|
||||
break
|
||||
}
|
||||
function getContainer (point) {
|
||||
let container
|
||||
|
||||
container = thisObject.payload.uiObject.getContainer(point)
|
||||
if (container !== undefined) { return container }
|
||||
|
||||
if (thisObject.container.frame.isThisScreenPointHere(point) === true) {
|
||||
return thisObject.container
|
||||
} else {
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
function pinToggle () {
|
||||
if (thisObject.isPinned !== true) {
|
||||
thisObject.isPinned = true
|
||||
thisObject.positionLocked = true
|
||||
} else {
|
||||
thisObject.isPinned = false
|
||||
}
|
||||
return thisObject.isPinned
|
||||
}
|
||||
|
||||
function physics () {
|
||||
thisObjectPhysics()
|
||||
thisObject.payload.uiObject.physics()
|
||||
}
|
||||
|
||||
function thisObjectPhysics () {
|
||||
// The radius also have a target.
|
||||
|
||||
if (Math.abs(thisObject.container.frame.radius - thisObject.targetRadius) >= 3) {
|
||||
if (thisObject.container.frame.radius < thisObject.targetRadius) {
|
||||
thisObject.container.frame.radius = thisObject.container.frame.radius + 3
|
||||
} else {
|
||||
thisObject.container.frame.radius = thisObject.container.frame.radius - 3
|
||||
}
|
||||
thisObject.container.eventHandler.raiseEvent('Dimmensions Changed', event)
|
||||
}
|
||||
|
||||
thisObject.type = pType
|
||||
// The imageSize also have a target.
|
||||
|
||||
thisObject.eventHandler.listenToEvent('onMouseOver', onMouseOver)
|
||||
canvas.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver)
|
||||
thisObject.eventHandler.listenToEvent('onMouseClick', onMouseClick)
|
||||
if (Math.abs(thisObject.currentImageSize - thisObject.targetImageSize) >= 1) {
|
||||
if (thisObject.currentImageSize < thisObject.targetImageSize) {
|
||||
thisObject.currentImageSize = thisObject.currentImageSize + 2
|
||||
} else {
|
||||
thisObject.currentImageSize = thisObject.currentImageSize - 2
|
||||
}
|
||||
}
|
||||
|
||||
if (callBackFunction !== undefined) { callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE) }
|
||||
} catch (err) {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> err.message = ' + err.message) }
|
||||
if (callBackFunction !== undefined) { callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) }
|
||||
// The fontSize also have a target.
|
||||
|
||||
if (Math.abs(thisObject.currentFontSize - thisObject.targetFontSize) >= 0.2) {
|
||||
if (thisObject.currentFontSize < thisObject.targetFontSize) {
|
||||
thisObject.currentFontSize = thisObject.currentFontSize + 0.2
|
||||
} else {
|
||||
thisObject.currentFontSize = thisObject.currentFontSize - 0.2
|
||||
}
|
||||
}
|
||||
|
||||
/* Floating object position in screen coordinates */
|
||||
|
||||
thisObject.payload.position.x = thisObject.container.frame.position.x
|
||||
thisObject.payload.position.y = thisObject.container.frame.position.y
|
||||
}
|
||||
|
||||
function onMouseOver (point) {
|
||||
if (thisObject.isOnFocus === false) {
|
||||
thisObject.targetRadius = thisObject.rawRadius * 6.0
|
||||
thisObject.targetImageSize = thisObject.rawImageSize * 2.0
|
||||
thisObject.targetFontSize = thisObject.rawFontSize * 2.0
|
||||
|
||||
thisObject.payload.uiObject.container.eventHandler.raiseEvent('onFocus', point)
|
||||
|
||||
thisObject.positionLocked = true
|
||||
|
||||
canvas.floatingSpace.container.eventHandler.raiseEvent('onFocusAquired', thisObject.container)
|
||||
thisObject.isOnFocus = true
|
||||
}
|
||||
}
|
||||
|
||||
function physicsLoop (callBackFunction) {
|
||||
try {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] initialize -> Entering function.') }
|
||||
function mouseOverFlotingSpace (point) {
|
||||
removeFocus()
|
||||
}
|
||||
|
||||
underlayingObject.physicsLoop()
|
||||
|
||||
if (callBackFunction !== undefined) { callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE) }
|
||||
} catch (err) {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] physicsLoop -> err.message = ' + err.message) }
|
||||
if (callBackFunction !== undefined) { callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) }
|
||||
function someoneAquiredFocus (container) {
|
||||
if (container.id !== thisObject.container.id) {
|
||||
removeFocus()
|
||||
}
|
||||
}
|
||||
|
||||
function onMouseOver () {
|
||||
thisObject.targetRadius = thisObject.rawRadius * 1.5
|
||||
thisObject.targetImageSize = thisObject.rawImageSize * 1.5
|
||||
thisObject.targetFontSize = thisObject.rawFontSize * 1.5
|
||||
function removeFocus () {
|
||||
if (thisObject.isOnFocus === true) {
|
||||
thisObject.targetRadius = thisObject.rawRadius * 1
|
||||
thisObject.targetImageSize = thisObject.rawImageSize * 1
|
||||
thisObject.targetFontSize = thisObject.rawFontSize * 1
|
||||
|
||||
underlayingObject.onMouseOver()
|
||||
}
|
||||
thisObject.payload.uiObject.container.eventHandler.raiseEvent('onNotFocus')
|
||||
|
||||
function onMouseNotOver () {
|
||||
thisObject.targetRadius = thisObject.rawRadius * 1
|
||||
thisObject.targetImageSize = thisObject.rawImageSize * 1
|
||||
thisObject.targetFontSize = thisObject.rawFontSize * 1
|
||||
|
||||
underlayingObject.onMouseNotOver()
|
||||
if (thisObject.isPinned !== true) {
|
||||
thisObject.positionLocked = false
|
||||
}
|
||||
thisObject.isOnFocus = false
|
||||
}
|
||||
}
|
||||
|
||||
function onMouseClick (pPoint) {
|
||||
underlayingObject.onMouseClick(pPoint, thisObject)
|
||||
let event = {
|
||||
point: pPoint,
|
||||
parent: thisObject
|
||||
}
|
||||
thisObject.payload.uiObject.container.eventHandler.raiseEvent('onMouseClick', event)
|
||||
}
|
||||
|
||||
function drawBackground () {
|
||||
underlayingObject.drawBackground(thisObject)
|
||||
thisObject.payload.uiObject.drawBackground()
|
||||
}
|
||||
|
||||
function drawMiddleground () {
|
||||
thisObject.payload.uiObject.drawMiddleground()
|
||||
}
|
||||
|
||||
function drawForeground () {
|
||||
underlayingObject.drawForeground(thisObject)
|
||||
thisObject.payload.uiObject.drawForeground()
|
||||
}
|
||||
|
||||
function drawOnFocus () {
|
||||
thisObject.payload.uiObject.drawOnFocus()
|
||||
}
|
||||
|
||||
function initializeMass (suggestedValue) {
|
||||
var mass = suggestedValue
|
||||
let mass = suggestedValue
|
||||
if (mass < 0.1) {
|
||||
mass = 0.1
|
||||
}
|
||||
@@ -159,14 +225,16 @@ function newFloatingObject () {
|
||||
}
|
||||
|
||||
function initializeRadius (suggestedValue) {
|
||||
var radius = suggestedValue
|
||||
let radius = suggestedValue
|
||||
if (radius < 2) {
|
||||
radius = 2
|
||||
}
|
||||
|
||||
thisObject.rawRadius = radius
|
||||
thisObject.targetRadius = radius
|
||||
thisObject.currentRadius = radius / 3
|
||||
thisObject.container.frame.radius = radius / 3
|
||||
|
||||
thisObject.container.eventHandler.raiseEvent('Dimmensions Changed', event)
|
||||
}
|
||||
|
||||
function initializeImageSize (suggestedValue) {
|
||||
@@ -192,12 +260,19 @@ function newFloatingObject () {
|
||||
}
|
||||
|
||||
function radomizeCurrentPosition (arroundPoint) {
|
||||
var position = {
|
||||
let position = {
|
||||
x: Math.floor((Math.random() * (200) - 100)) + arroundPoint.x,
|
||||
y: Math.floor((Math.random() * (200) - 100)) + arroundPoint.y
|
||||
}
|
||||
|
||||
thisObject.currentPosition = position
|
||||
// thisObject.container.frame.position = thisObject.container.frame.frameThisPoint(position)
|
||||
|
||||
thisObject.container.frame.position.x = position.x
|
||||
thisObject.container.frame.position.y = position.y
|
||||
|
||||
thisObject.payload.position = {}
|
||||
thisObject.payload.position.x = position.x
|
||||
thisObject.payload.position.y = position.y
|
||||
}
|
||||
|
||||
function radomizeCurrentSpeed () {
|
||||
@@ -227,14 +302,8 @@ function newFloatingObject () {
|
||||
|
||||
function updateMass () {
|
||||
|
||||
// thisObject.currentMass = thisObject.rawMass + thisObject.rawMass * thisObject.container.zoom.incrementM * thisObject.container.zoom.levelM;
|
||||
|
||||
}
|
||||
|
||||
function updateRadius () {
|
||||
|
||||
// thisObject.targetRadius = thisObject.rawRadius + thisObject.rawRadius * thisObject.container.zoom.incrementR * thisObject.container.zoom.levelR;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+80
-50
@@ -1,24 +1,45 @@
|
||||
|
||||
function newNote () {
|
||||
const MODULE_NAME = 'Note'
|
||||
|
||||
let thisObject = {
|
||||
|
||||
physicsLoop: physicsLoop,
|
||||
onMouseOver: onMouseOver,
|
||||
onMouseClick: onMouseClick,
|
||||
onMouseNotOver: onMouseNotOver,
|
||||
container: undefined,
|
||||
physics: physics,
|
||||
drawBackground: drawBackground,
|
||||
drawMiddleground: drawMiddleground,
|
||||
drawForeground: drawForeground,
|
||||
drawOnFocus: drawOnFocus,
|
||||
getContainer: getContainer,
|
||||
initialize: initialize
|
||||
|
||||
}
|
||||
|
||||
thisObject.container = newContainer()
|
||||
thisObject.container.initialize(MODULE_NAME, 'Circle')
|
||||
thisObject.container.isClickeable = false
|
||||
thisObject.container.isDraggeable = false
|
||||
thisObject.container.frame.radius = 0
|
||||
thisObject.container.frame.position.x = 0
|
||||
thisObject.container.frame.position.y = 0
|
||||
|
||||
return thisObject
|
||||
|
||||
function initialize (callBackFunction) {
|
||||
callBackFunction()
|
||||
function initialize () {
|
||||
thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver)
|
||||
thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick)
|
||||
thisObject.container.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver)
|
||||
}
|
||||
|
||||
function physicsLoop () {
|
||||
function getContainer (point) {
|
||||
let container
|
||||
|
||||
if (thisObject.container.frame.isThisPointHere(point, true) === true) {
|
||||
return thisObject.container
|
||||
} else {
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
function physics () {
|
||||
|
||||
}
|
||||
|
||||
@@ -30,8 +51,9 @@ function newNote () {
|
||||
|
||||
}
|
||||
|
||||
function onMouseClick (pPoint, pFloatingObject) {
|
||||
|
||||
function onMouseClick (event) {
|
||||
pPoint = event.point
|
||||
pFloatingObject = event.parent
|
||||
}
|
||||
|
||||
function drawBackground (pFloatingObject) {
|
||||
@@ -42,11 +64,11 @@ function newNote () {
|
||||
|
||||
point = viewPort.fitIntoVisibleArea(point)
|
||||
|
||||
if (pFloatingObject.currentRadius > 1) {
|
||||
if (pFloatingObject.container.frame.radius > 1) {
|
||||
/* Target Line */
|
||||
|
||||
browserCanvasContext.beginPath()
|
||||
browserCanvasContext.moveTo(pFloatingObject.currentPosition.x, pFloatingObject.currentPosition.y)
|
||||
browserCanvasContext.moveTo(pFloatingObject.container.frame.position.x, pFloatingObject.container.frame.position.y)
|
||||
browserCanvasContext.lineTo(point.x, point.y)
|
||||
browserCanvasContext.strokeStyle = 'rgba(204, 204, 204, 0.5)'
|
||||
browserCanvasContext.setLineDash([4, 2])
|
||||
@@ -55,7 +77,7 @@ function newNote () {
|
||||
browserCanvasContext.setLineDash([0, 0])
|
||||
}
|
||||
|
||||
if (pFloatingObject.currentRadius > 0.5) {
|
||||
if (pFloatingObject.container.frame.radius > 0.5) {
|
||||
/* Target Spot */
|
||||
|
||||
var radius = 1
|
||||
@@ -68,12 +90,20 @@ function newNote () {
|
||||
}
|
||||
}
|
||||
|
||||
function drawOnFocus () {
|
||||
|
||||
}
|
||||
|
||||
function drawMiddleground () {
|
||||
|
||||
}
|
||||
|
||||
function drawForeground (pFloatingObject) {
|
||||
const BUBBLE_CORNERS_RADIOUS = 5
|
||||
const BUBBLE_CORNERS_RADIUS = 5
|
||||
const TITLE_BAR_HEIGHT = 14
|
||||
|
||||
const BUBBLE_WIDTH = BUBBLE_CORNERS_RADIOUS + pFloatingObject.currentRadius * 4
|
||||
const BUBBLE_HEIGHT = BUBBLE_CORNERS_RADIOUS + pFloatingObject.currentRadius * 2
|
||||
const BUBBLE_WIDTH = BUBBLE_CORNERS_RADIUS + pFloatingObject.container.frame.radius * 4
|
||||
const BUBBLE_HEIGHT = BUBBLE_CORNERS_RADIUS + pFloatingObject.container.frame.radius * 2
|
||||
|
||||
let borderPoint1
|
||||
let borderPoint2
|
||||
@@ -81,31 +111,31 @@ function newNote () {
|
||||
let borderPoint4
|
||||
|
||||
let intialDisplace = {
|
||||
x: pFloatingObject.currentPosition.x - BUBBLE_WIDTH / 2,
|
||||
y: pFloatingObject.currentPosition.y - BUBBLE_HEIGHT / 2
|
||||
x: pFloatingObject.container.frame.position.x - BUBBLE_WIDTH / 2,
|
||||
y: pFloatingObject.container.frame.position.y - BUBBLE_HEIGHT / 2
|
||||
}
|
||||
|
||||
if (pFloatingObject.currentRadius > 5) {
|
||||
if (pFloatingObject.container.frame.radius > 5) {
|
||||
/* Rounded Background */
|
||||
|
||||
borderPoint1 = {
|
||||
x: intialDisplace.x + BUBBLE_CORNERS_RADIOUS,
|
||||
y: intialDisplace.y + BUBBLE_CORNERS_RADIOUS
|
||||
x: intialDisplace.x + BUBBLE_CORNERS_RADIUS,
|
||||
y: intialDisplace.y + BUBBLE_CORNERS_RADIUS
|
||||
}
|
||||
|
||||
borderPoint2 = {
|
||||
x: intialDisplace.x + BUBBLE_WIDTH - BUBBLE_CORNERS_RADIOUS,
|
||||
y: intialDisplace.y + BUBBLE_CORNERS_RADIOUS
|
||||
x: intialDisplace.x + BUBBLE_WIDTH - BUBBLE_CORNERS_RADIUS,
|
||||
y: intialDisplace.y + BUBBLE_CORNERS_RADIUS
|
||||
}
|
||||
|
||||
borderPoint3 = {
|
||||
x: intialDisplace.x + BUBBLE_WIDTH - BUBBLE_CORNERS_RADIOUS,
|
||||
y: intialDisplace.y + BUBBLE_HEIGHT - BUBBLE_CORNERS_RADIOUS
|
||||
x: intialDisplace.x + BUBBLE_WIDTH - BUBBLE_CORNERS_RADIUS,
|
||||
y: intialDisplace.y + BUBBLE_HEIGHT - BUBBLE_CORNERS_RADIUS
|
||||
}
|
||||
|
||||
borderPoint4 = {
|
||||
x: intialDisplace.x + BUBBLE_CORNERS_RADIOUS,
|
||||
y: intialDisplace.y + +BUBBLE_HEIGHT - BUBBLE_CORNERS_RADIOUS
|
||||
x: intialDisplace.x + BUBBLE_CORNERS_RADIUS,
|
||||
y: intialDisplace.y + +BUBBLE_HEIGHT - BUBBLE_CORNERS_RADIUS
|
||||
}
|
||||
|
||||
titleBarPoint1 = {
|
||||
@@ -123,14 +153,14 @@ function newNote () {
|
||||
browserCanvasContext.fillStyle = 'rgba(255, 249, 196, 0.75)'
|
||||
browserCanvasContext.beginPath()
|
||||
|
||||
browserCanvasContext.arc(borderPoint1.x, borderPoint1.y, BUBBLE_CORNERS_RADIOUS, 1.0 * Math.PI, 1.5 * Math.PI)
|
||||
browserCanvasContext.lineTo(borderPoint2.x, borderPoint2.y - BUBBLE_CORNERS_RADIOUS)
|
||||
browserCanvasContext.arc(borderPoint2.x, borderPoint2.y, BUBBLE_CORNERS_RADIOUS, 1.5 * Math.PI, 2.0 * Math.PI)
|
||||
browserCanvasContext.lineTo(borderPoint3.x + BUBBLE_CORNERS_RADIOUS, borderPoint3.y)
|
||||
browserCanvasContext.arc(borderPoint3.x, borderPoint3.y, BUBBLE_CORNERS_RADIOUS, 0 * Math.PI, 0.5 * Math.PI)
|
||||
browserCanvasContext.lineTo(borderPoint4.x, borderPoint4.y + BUBBLE_CORNERS_RADIOUS)
|
||||
browserCanvasContext.arc(borderPoint4.x, borderPoint4.y, BUBBLE_CORNERS_RADIOUS, 0.5 * Math.PI, 1.0 * Math.PI)
|
||||
browserCanvasContext.lineTo(borderPoint1.x - BUBBLE_CORNERS_RADIOUS, borderPoint1.y)
|
||||
browserCanvasContext.arc(borderPoint1.x, borderPoint1.y, BUBBLE_CORNERS_RADIUS, 1.0 * Math.PI, 1.5 * Math.PI)
|
||||
browserCanvasContext.lineTo(borderPoint2.x, borderPoint2.y - BUBBLE_CORNERS_RADIUS)
|
||||
browserCanvasContext.arc(borderPoint2.x, borderPoint2.y, BUBBLE_CORNERS_RADIUS, 1.5 * Math.PI, 2.0 * Math.PI)
|
||||
browserCanvasContext.lineTo(borderPoint3.x + BUBBLE_CORNERS_RADIUS, borderPoint3.y)
|
||||
browserCanvasContext.arc(borderPoint3.x, borderPoint3.y, BUBBLE_CORNERS_RADIUS, 0 * Math.PI, 0.5 * Math.PI)
|
||||
browserCanvasContext.lineTo(borderPoint4.x, borderPoint4.y + BUBBLE_CORNERS_RADIUS)
|
||||
browserCanvasContext.arc(borderPoint4.x, borderPoint4.y, BUBBLE_CORNERS_RADIUS, 0.5 * Math.PI, 1.0 * Math.PI)
|
||||
browserCanvasContext.lineTo(borderPoint1.x - BUBBLE_CORNERS_RADIUS, borderPoint1.y)
|
||||
|
||||
browserCanvasContext.closePath()
|
||||
|
||||
@@ -146,10 +176,10 @@ function newNote () {
|
||||
browserCanvasContext.beginPath()
|
||||
|
||||
browserCanvasContext.moveTo(titleBarPoint1.x, titleBarPoint1.y)
|
||||
browserCanvasContext.lineTo(borderPoint1.x - BUBBLE_CORNERS_RADIOUS, borderPoint1.y)
|
||||
browserCanvasContext.arc(borderPoint1.x, borderPoint1.y, BUBBLE_CORNERS_RADIOUS, 1.0 * Math.PI, 1.5 * Math.PI)
|
||||
browserCanvasContext.lineTo(borderPoint2.x, borderPoint2.y - BUBBLE_CORNERS_RADIOUS)
|
||||
browserCanvasContext.arc(borderPoint2.x, borderPoint2.y, BUBBLE_CORNERS_RADIOUS, 1.5 * Math.PI, 2.0 * Math.PI)
|
||||
browserCanvasContext.lineTo(borderPoint1.x - BUBBLE_CORNERS_RADIUS, borderPoint1.y)
|
||||
browserCanvasContext.arc(borderPoint1.x, borderPoint1.y, BUBBLE_CORNERS_RADIUS, 1.0 * Math.PI, 1.5 * Math.PI)
|
||||
browserCanvasContext.lineTo(borderPoint2.x, borderPoint2.y - BUBBLE_CORNERS_RADIUS)
|
||||
browserCanvasContext.arc(borderPoint2.x, borderPoint2.y, BUBBLE_CORNERS_RADIUS, 1.5 * Math.PI, 2.0 * Math.PI)
|
||||
browserCanvasContext.lineTo(titleBarPoint2.x, titleBarPoint2.y)
|
||||
|
||||
browserCanvasContext.closePath()
|
||||
@@ -160,12 +190,12 @@ function newNote () {
|
||||
browserCanvasContext.stroke()
|
||||
}
|
||||
|
||||
if (pFloatingObject.currentRadius > 0.5) {
|
||||
if (pFloatingObject.container.frame.radius > 0.5) {
|
||||
/* Image */
|
||||
|
||||
let imagePosition = {
|
||||
x: pFloatingObject.currentPosition.x,
|
||||
y: pFloatingObject.currentPosition.y + BUBBLE_HEIGHT / 2
|
||||
x: pFloatingObject.container.frame.position.x,
|
||||
y: pFloatingObject.container.frame.position.y + BUBBLE_HEIGHT / 2
|
||||
}
|
||||
|
||||
if (pFloatingObject.payloadImageId !== undefined) {
|
||||
@@ -187,10 +217,10 @@ function newNote () {
|
||||
|
||||
/* Labels */
|
||||
|
||||
if (pFloatingObject.currentRadius > 6) {
|
||||
if (pFloatingObject.container.frame.radius > 6) {
|
||||
browserCanvasContext.strokeStyle = pFloatingObject.labelStrokeStyle
|
||||
|
||||
const SIZE_PERCENTAGE = Math.trunc(pFloatingObject.currentRadius / pFloatingObject.targetRadius * 100) / 100
|
||||
const SIZE_PERCENTAGE = Math.trunc(pFloatingObject.container.frame.radius / pFloatingObject.targetRadius * 100) / 100
|
||||
let ALPHA
|
||||
|
||||
if (pFloatingObject.targetRadius > 0) {
|
||||
@@ -198,7 +228,7 @@ function newNote () {
|
||||
} else {
|
||||
// Object is dying...
|
||||
|
||||
ALPHA = Math.trunc((0.5 - (100 - pFloatingObject.currentRadius / 100)) * 100) / 100
|
||||
ALPHA = Math.trunc((0.5 - (100 - pFloatingObject.container.frame.radius / 100)) * 100) / 100
|
||||
|
||||
if (ALPHA < 0) { ALPHA = 0 }
|
||||
}
|
||||
@@ -214,7 +244,7 @@ function newNote () {
|
||||
|
||||
if (label !== undefined) {
|
||||
if (SIZE_PERCENTAGE > 0.9) {
|
||||
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.SECONDARY + ' Saira'
|
||||
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
|
||||
|
||||
let xOffset = label.length / 2 * fontSize * FONT_ASPECT_RATIO
|
||||
let yOffset = (TITLE_BAR_HEIGHT - fontSize) / 2 + 2
|
||||
@@ -283,8 +313,8 @@ function newNote () {
|
||||
let labelRow = labelRows[i]
|
||||
|
||||
let startingPosition = {
|
||||
x: pFloatingObject.currentPosition.x,
|
||||
y: pFloatingObject.currentPosition.y - labelRows.length / 2 * (fontSize * FONT_ASPECT_RATIO + 10)
|
||||
x: pFloatingObject.container.frame.position.x,
|
||||
y: pFloatingObject.container.frame.position.y - labelRows.length / 2 * (fontSize * FONT_ASPECT_RATIO + 10)
|
||||
}
|
||||
|
||||
labelPoint = {
|
||||
@@ -292,7 +322,7 @@ function newNote () {
|
||||
y: startingPosition.y + (i + 1) * (fontSize * FONT_ASPECT_RATIO + 10)
|
||||
}
|
||||
|
||||
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.SECONDARY + ' Saira'
|
||||
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
|
||||
browserCanvasContext.fillStyle = 'rgba(60, 60, 60, ' + ALPHA + ')'
|
||||
browserCanvasContext.fillText(labelRow, labelPoint.x, labelPoint.y)
|
||||
}
|
||||
|
||||
+29
-52
@@ -23,7 +23,8 @@ function newNoteSets () {
|
||||
let thisObject = {
|
||||
createNoteSet: createNoteSet,
|
||||
destroyNoteSet: destroyNoteSet,
|
||||
initialize: initialize
|
||||
initialize: initialize,
|
||||
finalize: finalize
|
||||
}
|
||||
|
||||
let noteSets = []
|
||||
@@ -31,21 +32,13 @@ function newNoteSets () {
|
||||
|
||||
return thisObject
|
||||
|
||||
function initialize (pFloatingLayer, callBackFunction) {
|
||||
/*
|
||||
During the initialization process, we receive the floatingLayer where all the floatingObjects we will be creating here will live at.
|
||||
*/
|
||||
function initialize (pFloatingLayer) {
|
||||
floatingLayer = pFloatingLayer
|
||||
}
|
||||
|
||||
try {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] initialize -> Entering function.') }
|
||||
|
||||
floatingLayer = pFloatingLayer
|
||||
|
||||
callBackFunction(GLOBAL.CUSTOM_OK_RESPONSE)
|
||||
} catch (err) {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> err = ' + err.stack) }
|
||||
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
|
||||
}
|
||||
function finalize () {
|
||||
floatingLayer.finalize()
|
||||
floatingLayer = undefined
|
||||
}
|
||||
|
||||
function createNoteSet (pPayload, pEventHandler, callBackFunction) {
|
||||
@@ -131,19 +124,7 @@ function newNoteSets () {
|
||||
Each time we identify a floatingObject that is not at the raw data anymore, we request the floatinglayer to kill it.
|
||||
*/
|
||||
|
||||
floatingLayer.killFloatingObject(floatingNote.floatingHandle, onObjectKilled)
|
||||
|
||||
function onObjectKilled (err) {
|
||||
if (err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] createNoteSet -> onNotesChanged -> Remove old Notes -> Floating Object Not Found.') }
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] createNoteSet -> onNotesChanged -> Remove old Notes -> Floating Object cannot be killed.') }
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] createNoteSet -> onNotesChanged -> Remove old Notes -> floatingNote.floatingHandle = ' + floatingNote.floatingHandle) }
|
||||
return
|
||||
}
|
||||
|
||||
if (INFO_LOG === true) { logger.write('[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> floatingNote.floatingHandle = ' + floatingNote.floatingHandle) }
|
||||
if (INFO_LOG === true) { logger.write('[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> Removed from Layer.') }
|
||||
}
|
||||
floatingLayer.removeFloatingObject(floatingNote.floatingHandle)
|
||||
} else {
|
||||
newFloatingNotes.push(floatingNote)
|
||||
|
||||
@@ -232,21 +213,18 @@ function newNoteSets () {
|
||||
*/
|
||||
|
||||
let floatingObject = newFloatingObject()
|
||||
floatingObject.initialize('Note', onInitialized)
|
||||
floatingObject.initialize('Note', '', floatingLayer)
|
||||
|
||||
function onInitialized (err) {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> onInitialized -> Entering function.') }
|
||||
floatingObject.payload = noteSet.payload
|
||||
floatingObject.payloadNoteIndex = i
|
||||
floatingObject.payloadImageId = noteSet.imageId
|
||||
|
||||
floatingObject.payload = noteSet.payload
|
||||
floatingObject.payloadNoteIndex = i
|
||||
floatingObject.payloadImageId = noteSet.imageId
|
||||
floatingObject.friction = 0.995
|
||||
|
||||
floatingObject.friction = 0.995
|
||||
|
||||
floatingObject.initializeMass(200)
|
||||
floatingObject.initializeMass(200)
|
||||
|
||||
// let bodyText = pNewNotes[i].body;
|
||||
let radius
|
||||
let radius
|
||||
|
||||
/*
|
||||
if (bodyText.length < 100) {
|
||||
@@ -255,27 +233,26 @@ function newNoteSets () {
|
||||
radius = bodyText.length;
|
||||
}
|
||||
*/
|
||||
radius = 50
|
||||
radius = 50
|
||||
|
||||
floatingObject.initializeRadius(radius)
|
||||
floatingObject.initializeImageSize(15)
|
||||
floatingObject.initializeRadius(radius)
|
||||
floatingObject.initializeImageSize(15)
|
||||
|
||||
floatingObject.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', 0.5)'
|
||||
floatingObject.labelStrokeStyle = 'rgba(60, 60, 60, 0.50)'
|
||||
floatingObject.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', 0.5)'
|
||||
floatingObject.labelStrokeStyle = 'rgba(60, 60, 60, 0.50)'
|
||||
|
||||
floatingLayer.addFloatingObject(floatingObject)
|
||||
floatingLayer.addFloatingObject(floatingObject)
|
||||
|
||||
if (INFO_LOG === true) { logger.write('[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> onInitialized -> New Note added to Layer.') }
|
||||
if (INFO_LOG === true) { logger.write('[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> onInitialized -> New Note added to Layer.') }
|
||||
|
||||
plotterNote.floatingHandle = floatingObject.handle
|
||||
plotterNote.floatingHandle = floatingObject.handle
|
||||
|
||||
if (INFO_LOG === true) { logger.write('[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> plotterNote.floatingHandle = ' + plotterNote.floatingHandle) }
|
||||
if (INFO_LOG === true) { logger.write('[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> plotterNote.floatingHandle = ' + plotterNote.floatingHandle) }
|
||||
|
||||
newFloatingNotes.push(plotterNote)
|
||||
newFloatingNotes.push(plotterNote)
|
||||
|
||||
if (INFO_LOG === true) { logger.write('[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> onInitialized -> Added to newFloatingNotes.') }
|
||||
if (INFO_LOG === true) { logger.write('[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> onInitialized -> newFloatingNotes.length = ' + newFloatingNotes.length) }
|
||||
}
|
||||
if (INFO_LOG === true) { logger.write('[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> onInitialized -> Added to newFloatingNotes.') }
|
||||
if (INFO_LOG === true) { logger.write('[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> onInitialized -> newFloatingNotes.length = ' + newFloatingNotes.length) }
|
||||
} else {
|
||||
newFloatingNotes.push(floatingNote)
|
||||
|
||||
@@ -322,7 +299,7 @@ function newNoteSets () {
|
||||
for (let j = 0; j < noteSet.floatingNotes.length; j++) {
|
||||
let floatingNote = noteSet.floatingNotes[j]
|
||||
|
||||
floatingLayer.killFloatingObject(floatingNote.floatingHandle)
|
||||
floatingLayer.removeFloatingObject(floatingNote.floatingHandle)
|
||||
}
|
||||
|
||||
noteSets.splice(i, 1) // Delete item from array.
|
||||
|
||||
@@ -1,22 +1,31 @@
|
||||
|
||||
function newProfileBall () {
|
||||
const MODULE_NAME = 'Profile Ball'
|
||||
|
||||
let thisObject = {
|
||||
|
||||
physicsLoop: physicsLoop,
|
||||
onMouseOver: onMouseOver,
|
||||
onMouseClick: onMouseClick,
|
||||
onMouseNotOver: onMouseNotOver,
|
||||
container: undefined,
|
||||
physics: physics,
|
||||
drawBackground: drawBackground,
|
||||
drawMiddleground: drawMiddleground,
|
||||
drawForeground: drawForeground,
|
||||
drawOnFocus: drawOnFocus,
|
||||
getContainer: getContainer,
|
||||
initialize: initialize
|
||||
|
||||
}
|
||||
|
||||
thisObject.container = newContainer()
|
||||
thisObject.container.initialize(MODULE_NAME, 'Circle')
|
||||
thisObject.container.isClickeable = false
|
||||
thisObject.container.isDraggeable = false
|
||||
thisObject.container.frame.radius = 0
|
||||
thisObject.container.frame.position.x = 0
|
||||
thisObject.container.frame.position.y = 0
|
||||
|
||||
let ballStringMenu = [
|
||||
{
|
||||
visible: false,
|
||||
imagePathOn: 'Images/menu.icon.on.1.gif',
|
||||
imagePathOff: 'Images/menu.icon.off.1.gif',
|
||||
iconPathOn: 'Images/menu.icon.on.1.gif',
|
||||
iconPathOff: 'Images/menu.icon.off.1.gif',
|
||||
rawRadius: 8,
|
||||
targetRadius: 0,
|
||||
currentRadius: 0,
|
||||
@@ -24,8 +33,8 @@ function newProfileBall () {
|
||||
}/*,
|
||||
{
|
||||
visible: false,
|
||||
imagePathOn: "Images/menu.icon.on.2.gif",
|
||||
imagePathOff: "Images/menu.icon.off.2.gif",
|
||||
iconPathOn: "Images/menu.icon.on.2.gif",
|
||||
iconPathOff: "Images/menu.icon.off.2.gif",
|
||||
rawRadius: 8,
|
||||
targetRadius: 0,
|
||||
currentRadius: 0,
|
||||
@@ -33,8 +42,8 @@ function newProfileBall () {
|
||||
},
|
||||
{
|
||||
visible: false,
|
||||
imagePathOn: "Images/menu.icon.on.3.gif",
|
||||
imagePathOff: "Images/menu.icon.off.3.gif",
|
||||
iconPathOn: "Images/menu.icon.on.3.gif",
|
||||
iconPathOff: "Images/menu.icon.off.3.gif",
|
||||
rawRadius: 8,
|
||||
targetRadius: 0,
|
||||
currentRadius: 0,
|
||||
@@ -42,8 +51,8 @@ function newProfileBall () {
|
||||
},
|
||||
{
|
||||
visible: false,
|
||||
imagePathOn: "Images/menu.icon.on.4.gif",
|
||||
imagePathOff: "Images/menu.icon.off.4.gif",
|
||||
iconPathOn: "Images/menu.icon.on.4.gif",
|
||||
iconPathOff: "Images/menu.icon.off.4.gif",
|
||||
rawRadius: 8,
|
||||
targetRadius: 0,
|
||||
currentRadius: 0,
|
||||
@@ -53,35 +62,39 @@ function newProfileBall () {
|
||||
|
||||
return thisObject
|
||||
|
||||
function initialize (callBackFunction) {
|
||||
function initialize () {
|
||||
for (let i = 0; i < ballStringMenu.length; i++) {
|
||||
let menuItem = ballStringMenu[i]
|
||||
|
||||
menuItem.iconOn = new Image()
|
||||
|
||||
menuItem.iconOn.onload = onImageLoad
|
||||
|
||||
function onImageLoad () {
|
||||
menuItem.iconOff = new Image()
|
||||
|
||||
menuItem.iconOff.onload = onImageLoad
|
||||
|
||||
function onImageLoad () {
|
||||
menuItem.canDrawIcon = true
|
||||
}
|
||||
|
||||
menuItem.iconOff.src = window.canvasApp.urlPrefix + menuItem.imagePathOff
|
||||
menuItem.iconOff.src = window.canvasApp.urlPrefix + menuItem.iconPathOff
|
||||
}
|
||||
|
||||
menuItem.iconOn.src = window.canvasApp.urlPrefix + menuItem.imagePathOn
|
||||
|
||||
menuItem.iconOn.src = window.canvasApp.urlPrefix + menuItem.iconPathOn
|
||||
menuItem.icon = menuItem.iconOn // The default value is ON.
|
||||
}
|
||||
|
||||
callBackFunction()
|
||||
thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver)
|
||||
thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick)
|
||||
thisObject.container.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver)
|
||||
}
|
||||
|
||||
function physicsLoop () {
|
||||
function getContainer (point) {
|
||||
let container
|
||||
|
||||
if (thisObject.container.frame.isThisPointHere(point, true) === true) {
|
||||
return thisObject.container
|
||||
} else {
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
function physics () {
|
||||
// The menuItems also have a target.
|
||||
|
||||
for (let i = 0; i < ballStringMenu.length; i++) {
|
||||
@@ -113,9 +126,12 @@ function newProfileBall () {
|
||||
}
|
||||
}
|
||||
|
||||
function onMouseClick (pPoint, pFloatingObject) {
|
||||
function onMouseClick (event) {
|
||||
/* What we need to do here is to check which menu item was clicked, if any. */
|
||||
|
||||
pPoint = event.point
|
||||
pFloatingObject = event.parent
|
||||
|
||||
let menuItemIndex
|
||||
|
||||
for (let i = 0; i < ballStringMenu.length; i++) {
|
||||
@@ -123,8 +139,8 @@ function newProfileBall () {
|
||||
|
||||
if (menuItem.canDrawIcon === true && menuItem.currentRadius > 1) {
|
||||
let position = {
|
||||
x: pFloatingObject.currentPosition.x + pFloatingObject.currentImageSize / 2 * Math.cos(toRadians(menuItem.angle)),
|
||||
y: pFloatingObject.currentPosition.y - pFloatingObject.currentImageSize / 2 * Math.sin(toRadians(menuItem.angle))
|
||||
x: pFloatingObject.container.frame.position.x + pFloatingObject.currentImageSize / 2 * Math.cos(toRadians(menuItem.angle)),
|
||||
y: pFloatingObject.container.frame.position.y - pFloatingObject.currentImageSize / 2 * Math.sin(toRadians(menuItem.angle))
|
||||
}
|
||||
|
||||
browserCanvasContext.drawImage(menuItem.icon, position.x, position.y, menuItem.currentRadius * 2, menuItem.currentRadius * 2)
|
||||
@@ -169,17 +185,17 @@ function newProfileBall () {
|
||||
|
||||
function drawBackground (pFloatingObject) {
|
||||
let point = {
|
||||
x: pFloatingObject.payload.profile.position.x,
|
||||
y: pFloatingObject.payload.profile.position.y
|
||||
x: pFloatingObject.payload.targetPosition.x,
|
||||
y: pFloatingObject.payload.targetPosition.y
|
||||
}
|
||||
|
||||
point = viewPort.fitIntoVisibleArea(point)
|
||||
|
||||
if (pFloatingObject.currentRadius > 1) {
|
||||
if (pFloatingObject.container.frame.radius > 1) {
|
||||
/* Target Line */
|
||||
|
||||
browserCanvasContext.beginPath()
|
||||
browserCanvasContext.moveTo(pFloatingObject.currentPosition.x, pFloatingObject.currentPosition.y)
|
||||
browserCanvasContext.moveTo(pFloatingObject.container.frame.position.x, pFloatingObject.container.frame.position.y)
|
||||
browserCanvasContext.lineTo(point.x, point.y)
|
||||
browserCanvasContext.strokeStyle = 'rgba(204, 204, 204, 0.5)'
|
||||
browserCanvasContext.setLineDash([4, 2])
|
||||
@@ -188,7 +204,7 @@ function newProfileBall () {
|
||||
browserCanvasContext.setLineDash([0, 0])
|
||||
}
|
||||
|
||||
if (pFloatingObject.currentRadius > 0.5) {
|
||||
if (pFloatingObject.container.frame.radius > 0.5) {
|
||||
/* Target Spot */
|
||||
|
||||
var radius = 1
|
||||
@@ -201,24 +217,32 @@ function newProfileBall () {
|
||||
}
|
||||
}
|
||||
|
||||
function drawOnFocus () {
|
||||
|
||||
}
|
||||
|
||||
function drawMiddleground () {
|
||||
|
||||
}
|
||||
|
||||
function drawForeground (pFloatingObject) {
|
||||
if (pFloatingObject.currentRadius > 5) {
|
||||
if (pFloatingObject.container.frame.radius > 5) {
|
||||
/* Contourn */
|
||||
|
||||
browserCanvasContext.beginPath()
|
||||
browserCanvasContext.arc(pFloatingObject.currentPosition.x, pFloatingObject.currentPosition.y, pFloatingObject.currentRadius, 0, Math.PI * 2, true)
|
||||
browserCanvasContext.arc(pFloatingObject.container.frame.position.x, pFloatingObject.container.frame.position.y, pFloatingObject.container.frame.radius, 0, Math.PI * 2, true)
|
||||
browserCanvasContext.closePath()
|
||||
browserCanvasContext.strokeStyle = 'rgba(30, 30, 30, 0.75)'
|
||||
browserCanvasContext.lineWidth = 1
|
||||
browserCanvasContext.stroke()
|
||||
}
|
||||
|
||||
if (pFloatingObject.currentRadius > 0.5) {
|
||||
if (pFloatingObject.container.frame.radius > 0.5) {
|
||||
/* Main FloatingObject */
|
||||
|
||||
var alphaA
|
||||
|
||||
if (pFloatingObject.currentRadius < 3) {
|
||||
if (pFloatingObject.container.frame.radius < 3) {
|
||||
alphaA = 1
|
||||
} else {
|
||||
alphaA = 0.75
|
||||
@@ -227,7 +251,7 @@ function newProfileBall () {
|
||||
alphaA = 0.75
|
||||
|
||||
browserCanvasContext.beginPath()
|
||||
browserCanvasContext.arc(pFloatingObject.currentPosition.x, pFloatingObject.currentPosition.y, pFloatingObject.currentRadius, 0, Math.PI * 2, true)
|
||||
browserCanvasContext.arc(pFloatingObject.container.frame.position.x, pFloatingObject.container.frame.position.y, pFloatingObject.container.frame.radius, 0, Math.PI * 2, true)
|
||||
browserCanvasContext.closePath()
|
||||
|
||||
browserCanvasContext.fillStyle = pFloatingObject.fillStyle
|
||||
@@ -243,12 +267,12 @@ function newProfileBall () {
|
||||
if (image !== null && image !== undefined) {
|
||||
browserCanvasContext.save()
|
||||
browserCanvasContext.beginPath()
|
||||
browserCanvasContext.arc(pFloatingObject.currentPosition.x, pFloatingObject.currentPosition.y, pFloatingObject.currentImageSize / 2, 0, Math.PI * 2, true)
|
||||
browserCanvasContext.arc(pFloatingObject.container.frame.position.x, pFloatingObject.container.frame.position.y, pFloatingObject.currentImageSize / 2, 0, Math.PI * 2, true)
|
||||
browserCanvasContext.closePath()
|
||||
browserCanvasContext.clip()
|
||||
browserCanvasContext.drawImage(image, pFloatingObject.currentPosition.x - pFloatingObject.currentImageSize / 2, pFloatingObject.currentPosition.y - pFloatingObject.currentImageSize / 2, pFloatingObject.currentImageSize, pFloatingObject.currentImageSize)
|
||||
browserCanvasContext.drawImage(image, pFloatingObject.container.frame.position.x - pFloatingObject.currentImageSize / 2, pFloatingObject.container.frame.position.y - pFloatingObject.currentImageSize / 2, pFloatingObject.currentImageSize, pFloatingObject.currentImageSize)
|
||||
browserCanvasContext.beginPath()
|
||||
browserCanvasContext.arc(pFloatingObject.currentPosition.x - pFloatingObject.currentImageSize / 2, pFloatingObject.currentPosition.y - pFloatingObject.currentImageSize / 2, pFloatingObject.currentImageSize / 2, 0, Math.PI * 2, true)
|
||||
browserCanvasContext.arc(pFloatingObject.container.frame.position.x - pFloatingObject.currentImageSize / 2, pFloatingObject.container.frame.position.y - pFloatingObject.currentImageSize / 2, pFloatingObject.currentImageSize / 2, 0, Math.PI * 2, true)
|
||||
browserCanvasContext.clip()
|
||||
browserCanvasContext.closePath()
|
||||
browserCanvasContext.restore()
|
||||
@@ -262,8 +286,8 @@ function newProfileBall () {
|
||||
|
||||
if (menuItem.canDrawIcon === true && menuItem.currentRadius > 1) {
|
||||
let position = {
|
||||
x: pFloatingObject.currentPosition.x + pFloatingObject.currentImageSize / 2 * Math.cos(toRadians(menuItem.angle)),
|
||||
y: pFloatingObject.currentPosition.y - pFloatingObject.currentImageSize / 2 * Math.sin(toRadians(menuItem.angle))
|
||||
x: pFloatingObject.container.frame.position.x + pFloatingObject.currentImageSize / 2 * Math.cos(toRadians(menuItem.angle)),
|
||||
y: pFloatingObject.container.frame.position.y - pFloatingObject.currentImageSize / 2 * Math.sin(toRadians(menuItem.angle))
|
||||
}
|
||||
|
||||
browserCanvasContext.drawImage(menuItem.icon, position.x - menuItem.currentRadius, position.y - menuItem.currentRadius, menuItem.currentRadius * 2, menuItem.currentRadius * 2)
|
||||
@@ -272,38 +296,38 @@ function newProfileBall () {
|
||||
|
||||
/* Label Text */
|
||||
|
||||
if (pFloatingObject.currentRadius > 6) {
|
||||
if (pFloatingObject.container.frame.radius > 6) {
|
||||
browserCanvasContext.strokeStyle = pFloatingObject.labelStrokeStyle
|
||||
|
||||
let labelPoint
|
||||
let fontSize = pFloatingObject.currentFontSize
|
||||
|
||||
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.SECONDARY + ' Saira'
|
||||
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
|
||||
|
||||
let label
|
||||
|
||||
label = pFloatingObject.payload.profile.upLabel
|
||||
label = pFloatingObject.payload.profile.subTitle
|
||||
|
||||
if (label !== undefined) {
|
||||
labelPoint = {
|
||||
x: pFloatingObject.currentPosition.x - label.length / 2 * fontSize * FONT_ASPECT_RATIO,
|
||||
y: pFloatingObject.currentPosition.y - pFloatingObject.currentImageSize / 2 - fontSize * FONT_ASPECT_RATIO - 10
|
||||
x: pFloatingObject.container.frame.position.x - label.length / 2 * fontSize * FONT_ASPECT_RATIO,
|
||||
y: pFloatingObject.container.frame.position.y - pFloatingObject.currentImageSize / 2 - fontSize * FONT_ASPECT_RATIO - 10
|
||||
}
|
||||
|
||||
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.SECONDARY + ' Saira'
|
||||
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
|
||||
browserCanvasContext.fillStyle = pFloatingObject.labelStrokeStyle
|
||||
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y)
|
||||
}
|
||||
|
||||
label = pFloatingObject.payload.profile.downLabel
|
||||
label = pFloatingObject.payload.profile.title
|
||||
|
||||
if (label !== undefined) {
|
||||
labelPoint = {
|
||||
x: pFloatingObject.currentPosition.x - label.length / 2 * fontSize * FONT_ASPECT_RATIO,
|
||||
y: pFloatingObject.currentPosition.y + pFloatingObject.currentImageSize / 2 + fontSize * FONT_ASPECT_RATIO + 15
|
||||
x: pFloatingObject.container.frame.position.x - label.length / 2 * fontSize * FONT_ASPECT_RATIO,
|
||||
y: pFloatingObject.container.frame.position.y + pFloatingObject.currentImageSize / 2 + fontSize * FONT_ASPECT_RATIO + 15
|
||||
}
|
||||
|
||||
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.SECONDARY + ' Saira'
|
||||
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
|
||||
browserCanvasContext.fillStyle = pFloatingObject.labelStrokeStyle
|
||||
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
|
||||
|
||||
function newProfileBalls () {
|
||||
const MODULE_NAME = 'Profile Balls'
|
||||
const INFO_LOG = false
|
||||
@@ -6,11 +6,11 @@ function newProfileBalls () {
|
||||
const logger = newWebDebugLog()
|
||||
logger.fileName = MODULE_NAME
|
||||
|
||||
/*
|
||||
/*
|
||||
|
||||
This object deals with Profile Balls, a type of Floating Object that shows profile info in a floating ball.
|
||||
This object deals with Profile Balls, a type of Floating Object that shows profile info in a floating ball.
|
||||
|
||||
*/
|
||||
*/
|
||||
|
||||
let thisObject = {
|
||||
|
||||
@@ -25,54 +25,38 @@ function newProfileBalls () {
|
||||
|
||||
return thisObject
|
||||
|
||||
function finalize () {
|
||||
try {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] finalize -> Entering function.') }
|
||||
|
||||
floatingLayer.finalize()
|
||||
} catch (err) {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] finalize -> err = ' + err.stack) }
|
||||
}
|
||||
function initialize (pFloatingLayer) {
|
||||
floatingLayer = pFloatingLayer
|
||||
}
|
||||
|
||||
function initialize (pFloatingLayer, callBackFunction) {
|
||||
try {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] initialize -> Entering function.') }
|
||||
|
||||
floatingLayer = pFloatingLayer
|
||||
|
||||
callBackFunction(GLOBAL.CUSTOM_OK_RESPONSE)
|
||||
} catch (err) {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> err = ' + err.stack) }
|
||||
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
|
||||
}
|
||||
function finalize () {
|
||||
floatingLayer.finalize()
|
||||
floatingLayer = undefined
|
||||
}
|
||||
|
||||
function createNewProfileBall (pPayload, callBackFunction) {
|
||||
let floatingObject = newFloatingObject()
|
||||
floatingObject.initialize('Profile Ball', onInitialized)
|
||||
floatingObject.initialize('Profile Ball', '', floatingLayer)
|
||||
|
||||
function onInitialized (err) {
|
||||
floatingObject.payload = pPayload
|
||||
floatingObject.payload = pPayload
|
||||
|
||||
floatingObject.friction = 0.995
|
||||
floatingObject.friction = 0.995
|
||||
|
||||
floatingObject.initializeMass(100)
|
||||
floatingObject.initializeRadius(30)
|
||||
floatingObject.initializeImageSize(50)
|
||||
floatingObject.initializeFontSize(10)
|
||||
floatingObject.initializeMass(100)
|
||||
floatingObject.initializeRadius(30)
|
||||
floatingObject.initializeImageSize(50)
|
||||
floatingObject.initializeFontSize(10)
|
||||
|
||||
floatingObject.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', 0.5)'
|
||||
floatingObject.labelStrokeStyle = 'rgba(60, 60, 60, 0.50)'
|
||||
floatingObject.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', 0.5)'
|
||||
floatingObject.labelStrokeStyle = 'rgba(60, 60, 60, 0.50)'
|
||||
|
||||
floatingLayer.addFloatingObject(floatingObject)
|
||||
floatingLayer.addFloatingObject(floatingObject)
|
||||
|
||||
callBackFunction(GLOBAL.CUSTOM_OK_RESPONSE, floatingObject.handle)
|
||||
}
|
||||
callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE, floatingObject.handle)
|
||||
}
|
||||
|
||||
function destroyProfileBall (pFloatingObjectHandle) {
|
||||
floatingLayer.killFloatingObject(pFloatingObjectHandle)
|
||||
floatingLayer.removeFloatingObject(pFloatingObjectHandle)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,369 @@
|
||||
|
||||
function newStrategyPart () {
|
||||
const MODULE_NAME = 'Strategy Part'
|
||||
const ERROR_LOG = true
|
||||
|
||||
const logger = newWebDebugLog()
|
||||
logger.fileName = MODULE_NAME
|
||||
|
||||
let thisObject = {
|
||||
fitFunction: undefined,
|
||||
isVisibleFunction: undefined,
|
||||
type: undefined,
|
||||
menu: undefined,
|
||||
isOnFocus: false,
|
||||
container: undefined,
|
||||
payload: undefined,
|
||||
codeEditor: undefined,
|
||||
partTitle: undefined,
|
||||
physics: physics,
|
||||
drawBackground: drawBackground,
|
||||
drawMiddleground: drawMiddleground,
|
||||
drawForeground: drawForeground,
|
||||
drawOnFocus: drawOnFocus,
|
||||
getContainer: getContainer,
|
||||
finalize: finalize,
|
||||
initialize: initialize
|
||||
}
|
||||
|
||||
thisObject.container = newContainer()
|
||||
thisObject.container.initialize(MODULE_NAME, 'Circle')
|
||||
thisObject.container.isClickeable = false
|
||||
thisObject.container.isDraggeable = false
|
||||
thisObject.container.frame.radius = 0
|
||||
thisObject.container.frame.position.x = 0
|
||||
thisObject.container.frame.position.y = 0
|
||||
|
||||
let icon
|
||||
|
||||
let selfFocusEventSubscriptionId
|
||||
let selfNotFocuskEventSubscriptionId
|
||||
let selfDisplaceEventSubscriptionId
|
||||
|
||||
return thisObject
|
||||
|
||||
function finalize () {
|
||||
thisObject.container.eventHandler.stopListening(selfFocusEventSubscriptionId)
|
||||
thisObject.container.eventHandler.stopListening(selfNotFocuskEventSubscriptionId)
|
||||
thisObject.container.eventHandler.stopListening(selfDisplaceEventSubscriptionId)
|
||||
|
||||
thisObject.container.finalize()
|
||||
thisObject.container = undefined
|
||||
thisObject.payload = undefined
|
||||
thisObject.menu.finalize()
|
||||
thisObject.menu = undefined
|
||||
thisObject.partTitle.finalize()
|
||||
thisObject.partTitle = undefined
|
||||
thisObject.fitFunction = undefined
|
||||
thisObject.isVisibleFunction = undefined
|
||||
|
||||
if (thisObject.codeEditor !== undefined) {
|
||||
thisObject.codeEditor.finalize()
|
||||
thisObject.codeEditor = undefined
|
||||
}
|
||||
|
||||
icon = undefined
|
||||
}
|
||||
|
||||
function initialize (payload, menuItemsInitialValues) {
|
||||
thisObject.payload = payload
|
||||
|
||||
/* Initialize the Menu */
|
||||
|
||||
thisObject.menu = newCircularMenu()
|
||||
thisObject.menu.initialize(menuItemsInitialValues, thisObject.payload)
|
||||
thisObject.menu.container.connectToParent(thisObject.container, false, false, true, true, false, false, true, true)
|
||||
|
||||
/* Initialize Part Title */
|
||||
|
||||
thisObject.partTitle = newStrategyPartTitle()
|
||||
thisObject.partTitle.isVisibleFunction = thisObject.isVisibleFunction
|
||||
thisObject.partTitle.container.connectToParent(thisObject.container, false, false, true, true, false, false, true, true)
|
||||
thisObject.partTitle.initialize(thisObject.payload)
|
||||
|
||||
/* Load Part Image */
|
||||
|
||||
iconPhysics()
|
||||
|
||||
selfFocusEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onFocus', onFocus)
|
||||
selfNotFocuskEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onNotFocus', onNotFocus)
|
||||
selfDisplaceEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onDisplace', onDisplace)
|
||||
}
|
||||
|
||||
function getContainer (point) {
|
||||
let container
|
||||
|
||||
if (thisObject.codeEditor !== undefined) {
|
||||
container = thisObject.codeEditor.getContainer(point)
|
||||
if (container !== undefined) { return container }
|
||||
}
|
||||
|
||||
container = thisObject.partTitle.getContainer(point)
|
||||
if (container !== undefined) { return container }
|
||||
|
||||
container = thisObject.menu.getContainer(point)
|
||||
if (container !== undefined) { return container }
|
||||
|
||||
if (thisObject.container.frame.isThisPointHere(point, true) === true) {
|
||||
return thisObject.container
|
||||
} else {
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
function physics () {
|
||||
thisObject.menu.physics()
|
||||
thisObject.partTitle.physics()
|
||||
|
||||
if (thisObject.codeEditor !== undefined) {
|
||||
thisObject.codeEditor.physics()
|
||||
}
|
||||
|
||||
if (thisObject.payload.chainParent === undefined) {
|
||||
thisObject.payload.targetPosition.x = canvas.floatingSpace.container.frame.width / 2,
|
||||
thisObject.payload.targetPosition.y = canvas.floatingSpace.container.frame.height / 2
|
||||
} else {
|
||||
thisObject.payload.targetPosition.x = thisObject.payload.chainParent.payload.position.x
|
||||
thisObject.payload.targetPosition.y = thisObject.payload.chainParent.payload.position.y
|
||||
}
|
||||
|
||||
iconPhysics()
|
||||
}
|
||||
|
||||
function iconPhysics () {
|
||||
icon = canvas.strategySpace.iconByPartType.get(thisObject.payload.node.type)
|
||||
}
|
||||
|
||||
function onFocus () {
|
||||
thisObject.isOnFocus = true
|
||||
}
|
||||
|
||||
function onNotFocus () {
|
||||
thisObject.isOnFocus = false
|
||||
if (thisObject.codeEditor !== undefined) {
|
||||
thisObject.codeEditor.deactivate()
|
||||
}
|
||||
}
|
||||
|
||||
function onDisplace (event) {
|
||||
thisObject.partTitle.exitEditMode()
|
||||
}
|
||||
|
||||
function drawBackground () {
|
||||
if (thisObject.isOnFocus === false) {
|
||||
drawConnectingLine()
|
||||
thisObject.menu.drawBackground()
|
||||
}
|
||||
}
|
||||
|
||||
function drawMiddleground () {
|
||||
if (thisObject.isOnFocus === false) {
|
||||
drawText()
|
||||
thisObject.partTitle.draw()
|
||||
}
|
||||
}
|
||||
|
||||
function drawForeground () {
|
||||
if (thisObject.isOnFocus === false) {
|
||||
drawBodyAndPicture()
|
||||
thisObject.menu.drawForeground()
|
||||
}
|
||||
}
|
||||
|
||||
function drawOnFocus () {
|
||||
if (thisObject.isOnFocus === true) {
|
||||
drawConnectingLine()
|
||||
thisObject.menu.drawBackground()
|
||||
|
||||
if (thisObject.codeEditor !== undefined) {
|
||||
thisObject.codeEditor.drawBackground()
|
||||
thisObject.codeEditor.drawForeground()
|
||||
}
|
||||
|
||||
drawText()
|
||||
thisObject.partTitle.draw()
|
||||
|
||||
if (thisObject.codeEditor !== undefined) {
|
||||
if (thisObject.codeEditor.visible === false) {
|
||||
drawBodyAndPicture()
|
||||
thisObject.menu.drawForeground()
|
||||
}
|
||||
} else {
|
||||
drawBodyAndPicture()
|
||||
thisObject.menu.drawForeground()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function drawConnectingLine () {
|
||||
if (thisObject.payload.chainParent === undefined) { return }
|
||||
|
||||
let targetPoint = {
|
||||
x: thisObject.payload.targetPosition.x,
|
||||
y: thisObject.payload.targetPosition.y
|
||||
}
|
||||
|
||||
let position = {
|
||||
x: 0,
|
||||
y: 0
|
||||
}
|
||||
|
||||
targetPoint = canvas.floatingSpace.container.frame.frameThisPoint(targetPoint)
|
||||
position = thisObject.container.frame.frameThisPoint(position)
|
||||
|
||||
if (thisObject.container.frame.radius > 1) {
|
||||
/* Target Line */
|
||||
|
||||
browserCanvasContext.beginPath()
|
||||
browserCanvasContext.moveTo(position.x, position.y)
|
||||
browserCanvasContext.lineTo(targetPoint.x, targetPoint.y)
|
||||
browserCanvasContext.strokeStyle = 'rgba(204, 204, 204, 0.5)'
|
||||
browserCanvasContext.setLineDash([1, 4])
|
||||
browserCanvasContext.lineWidth = 1
|
||||
browserCanvasContext.stroke()
|
||||
browserCanvasContext.setLineDash([0, 0])
|
||||
}
|
||||
|
||||
if (thisObject.container.frame.radius > 0.5) {
|
||||
/* Target Spot */
|
||||
|
||||
let radius = 1
|
||||
|
||||
browserCanvasContext.beginPath()
|
||||
browserCanvasContext.arc(targetPoint.x, targetPoint.y, radius, 0, Math.PI * 2, true)
|
||||
browserCanvasContext.closePath()
|
||||
browserCanvasContext.fillStyle = 'rgba(30, 30, 30, 1)'
|
||||
browserCanvasContext.fill()
|
||||
}
|
||||
}
|
||||
|
||||
function drawText () {
|
||||
/* Text Follows */
|
||||
let position = {
|
||||
x: 0,
|
||||
y: 0
|
||||
}
|
||||
|
||||
position = thisObject.container.frame.frameThisPoint(position)
|
||||
|
||||
let radius = thisObject.container.frame.radius
|
||||
/* Label Text */
|
||||
let labelPoint
|
||||
let fontSize = thisObject.payload.floatingObject.currentFontSize
|
||||
let label
|
||||
|
||||
if (radius > 6) {
|
||||
const MAX_LABEL_LENGTH = 30
|
||||
|
||||
label = thisObject.payload.subTitle
|
||||
label = addIndexNumber(label)
|
||||
|
||||
if (label !== undefined) {
|
||||
if (label.length > MAX_LABEL_LENGTH) {
|
||||
label = label.substring(0, MAX_LABEL_LENGTH) + '...'
|
||||
}
|
||||
|
||||
labelPoint = {
|
||||
x: position.x - label.length / 2 * fontSize * FONT_ASPECT_RATIO - 5,
|
||||
y: position.y + radius * 2 / 3 + fontSize * FONT_ASPECT_RATIO + 15
|
||||
}
|
||||
|
||||
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
|
||||
browserCanvasContext.fillStyle = thisObject.payload.floatingObject.labelStrokeStyle
|
||||
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function addIndexNumber (label) {
|
||||
switch (thisObject.payload.node.type) {
|
||||
case 'Phase': {
|
||||
let parent = thisObject.payload.parentNode
|
||||
for (let i = 0; i < parent.phases.length; i++) {
|
||||
let phase = parent.phases[i]
|
||||
if (phase.id === thisObject.payload.node.id) {
|
||||
label = label + ' #' + (i + 1)
|
||||
return label
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
case 'Situation': {
|
||||
let parent = thisObject.payload.parentNode
|
||||
for (let i = 0; i < parent.situations.length; i++) {
|
||||
let situation = parent.situations[i]
|
||||
if (situation.id === thisObject.payload.node.id) {
|
||||
label = label + ' #' + (i + 1)
|
||||
return label
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
case 'Condition': {
|
||||
let parent = thisObject.payload.parentNode
|
||||
for (let i = 0; i < parent.conditions.length; i++) {
|
||||
let condition = parent.conditions[i]
|
||||
if (condition.id === thisObject.payload.node.id) {
|
||||
label = label + ' #' + (i + 1)
|
||||
return label
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
default: {
|
||||
return label
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function drawBodyAndPicture () {
|
||||
let position = {
|
||||
x: thisObject.container.frame.position.x,
|
||||
y: thisObject.container.frame.position.y
|
||||
}
|
||||
|
||||
position = thisObject.container.frame.frameThisPoint(position)
|
||||
|
||||
let radius = thisObject.container.frame.radius
|
||||
|
||||
if (radius > 0.5) {
|
||||
const VISIBLE_RADIUS = 5
|
||||
|
||||
let visiblePosition = {
|
||||
x: thisObject.container.frame.position.x,
|
||||
y: thisObject.container.frame.position.y
|
||||
}
|
||||
|
||||
visiblePosition = thisObject.container.frame.frameThisPoint(visiblePosition)
|
||||
visiblePosition = thisObject.fitFunction(visiblePosition)
|
||||
|
||||
browserCanvasContext.beginPath()
|
||||
browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true)
|
||||
browserCanvasContext.closePath()
|
||||
|
||||
browserCanvasContext.fillStyle = thisObject.payload.floatingObject.fillStyle
|
||||
|
||||
browserCanvasContext.fill()
|
||||
|
||||
browserCanvasContext.beginPath()
|
||||
browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS / 2, 0, Math.PI * 2, true)
|
||||
browserCanvasContext.closePath()
|
||||
|
||||
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.BLACK + ', 1)'
|
||||
|
||||
browserCanvasContext.fill()
|
||||
}
|
||||
|
||||
/* Image */
|
||||
|
||||
if (icon !== undefined) {
|
||||
if (icon.canDrawIcon === true) {
|
||||
browserCanvasContext.drawImage(
|
||||
icon, position.x - thisObject.payload.floatingObject.currentImageSize / 2,
|
||||
position.y - thisObject.payload.floatingObject.currentImageSize / 2,
|
||||
thisObject.payload.floatingObject.currentImageSize,
|
||||
thisObject.payload.floatingObject.currentImageSize)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,606 @@
|
||||
|
||||
function newStrategyPartConstructor () {
|
||||
const MODULE_NAME = 'Strategy Part Constructor'
|
||||
const ERROR_LOG = true
|
||||
const logger = newWebDebugLog()
|
||||
logger.fileName = MODULE_NAME
|
||||
|
||||
let thisObject = {
|
||||
|
||||
createStrategyPart: createStrategyPart,
|
||||
destroyStrategyPart: destroyStrategyPart,
|
||||
initialize: initialize,
|
||||
finalize: finalize
|
||||
|
||||
}
|
||||
|
||||
let floatingLayer
|
||||
|
||||
return thisObject
|
||||
|
||||
function finalize () {
|
||||
floatingLayer = undefined
|
||||
|
||||
payload.uiObject.finalize()
|
||||
payload.uiObject = undefined
|
||||
}
|
||||
|
||||
function initialize (pFloatingLayer) {
|
||||
floatingLayer = pFloatingLayer
|
||||
}
|
||||
|
||||
function createStrategyPart (payload) {
|
||||
let floatingObject = newFloatingObject()
|
||||
floatingObject.fitFunction = canvas.floatingSpace.fitIntoVisibleArea
|
||||
floatingObject.container.connectToParent(canvas.floatingSpace.container, false, false, false, false, false, false, false, false)
|
||||
floatingObject.initialize('Strategy Part', payload)
|
||||
payload.floatingObject = floatingObject
|
||||
|
||||
let strategyPart = newStrategyPart()
|
||||
strategyPart.fitFunction = canvas.floatingSpace.fitIntoVisibleArea
|
||||
strategyPart.isVisibleFunction = canvas.floatingSpace.isThisPointVisible
|
||||
let menuItemsInitialValues = getMenuItemsInitialValues(strategyPart, floatingObject, payload)
|
||||
strategyPart.initialize(payload, menuItemsInitialValues)
|
||||
strategyPart.container.connectToParent(floatingObject.container, false, false, true, true, false, false, true, true, true)
|
||||
payload.uiObject = strategyPart
|
||||
|
||||
setFloatingObjectBasicProperties(floatingObject, payload)
|
||||
|
||||
floatingLayer.addFloatingObject(floatingObject)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
function getMenuItemsInitialValues (strategyPart, floatingObject, payload) {
|
||||
let menuItemsInitialValues = []
|
||||
switch (payload.node.type) {
|
||||
case 'Trading System': {
|
||||
floatingObject.isPinned = true
|
||||
floatingObject.positionLocked = true
|
||||
menuItemsInitialValues = [
|
||||
{
|
||||
action: 'Pin / Unpin',
|
||||
actionFunction: floatingObject.pinToggle,
|
||||
currentStatus: true,
|
||||
label: undefined,
|
||||
visible: false,
|
||||
iconPathOn: 'target',
|
||||
iconPathOff: 'security',
|
||||
rawRadius: 8,
|
||||
targetRadius: 0,
|
||||
currentRadius: 0,
|
||||
angle: -135
|
||||
},
|
||||
{
|
||||
action: 'Reload Trading System',
|
||||
actionFunction: payload.onMenuItemClick,
|
||||
label: 'Reload',
|
||||
visible: false,
|
||||
iconPathOn: 'vector',
|
||||
iconPathOff: 'vector',
|
||||
rawRadius: 8,
|
||||
targetRadius: 0,
|
||||
currentRadius: 0,
|
||||
angle: -60
|
||||
},
|
||||
{
|
||||
action: 'Save Trading System',
|
||||
actionFunction: payload.onMenuItemClick,
|
||||
label: 'Save Changes',
|
||||
workingLabel: 'Saving...',
|
||||
workDoneLabel: 'Saved',
|
||||
workFailedLabel: 'Not Saved',
|
||||
visible: false,
|
||||
iconPathOn: 'upload',
|
||||
iconPathOff: 'upload',
|
||||
rawRadius: 8,
|
||||
targetRadius: 0,
|
||||
currentRadius: 0,
|
||||
angle: -20
|
||||
},
|
||||
{
|
||||
action: 'New Strategy',
|
||||
actionFunction: payload.onMenuItemClick,
|
||||
label: 'New Strategy',
|
||||
visible: false,
|
||||
iconPathOn: 'quality',
|
||||
iconPathOff: 'quality',
|
||||
relatedStrategyPart: 'Strategy',
|
||||
rawRadius: 8,
|
||||
targetRadius: 0,
|
||||
currentRadius: 0,
|
||||
angle: 20
|
||||
},
|
||||
{
|
||||
action: 'Open Settings',
|
||||
actionFunction: payload.onMenuItemClick,
|
||||
label: 'Settings',
|
||||
visible: false,
|
||||
iconPathOn: 'tools',
|
||||
iconPathOff: 'tools',
|
||||
rawRadius: 8,
|
||||
targetRadius: 0,
|
||||
currentRadius: 0,
|
||||
angle: 60
|
||||
}]
|
||||
break
|
||||
}
|
||||
case 'Strategy': {
|
||||
menuItemsInitialValues = [
|
||||
{
|
||||
action: 'Pin / Unpin',
|
||||
actionFunction: floatingObject.pinToggle,
|
||||
currentStatus: false,
|
||||
label: undefined,
|
||||
visible: false,
|
||||
iconPathOn: 'target',
|
||||
iconPathOff: 'security',
|
||||
rawRadius: 8,
|
||||
targetRadius: 0,
|
||||
currentRadius: 0,
|
||||
angle: -135
|
||||
},
|
||||
{
|
||||
action: 'Delete Strategy',
|
||||
actionFunction: payload.onMenuItemClick,
|
||||
label: 'Delete This Strategy',
|
||||
visible: false,
|
||||
iconPathOn: 'trash',
|
||||
iconPathOff: 'trash',
|
||||
rawRadius: 8,
|
||||
targetRadius: 0,
|
||||
currentRadius: 0,
|
||||
angle: -20
|
||||
},
|
||||
{
|
||||
action: 'Open Settings',
|
||||
actionFunction: payload.onMenuItemClick,
|
||||
label: 'Settings',
|
||||
visible: false,
|
||||
iconPathOn: 'tools',
|
||||
iconPathOff: 'tools',
|
||||
rawRadius: 8,
|
||||
targetRadius: 0,
|
||||
currentRadius: 0,
|
||||
angle: 20
|
||||
}]
|
||||
break
|
||||
}
|
||||
case 'Strategy Entry Event': {
|
||||
menuItemsInitialValues = [
|
||||
{
|
||||
action: 'Pin / Unpin',
|
||||
actionFunction: floatingObject.pinToggle,
|
||||
currentStatus: false,
|
||||
label: undefined,
|
||||
visible: false,
|
||||
iconPathOn: 'target',
|
||||
iconPathOff: 'security',
|
||||
rawRadius: 8,
|
||||
targetRadius: 0,
|
||||
currentRadius: 0,
|
||||
angle: -135
|
||||
},
|
||||
{
|
||||
action: 'Add Situation',
|
||||
actionFunction: payload.onMenuItemClick,
|
||||
label: 'Add Situation',
|
||||
visible: false,
|
||||
iconPathOn: 'attractive',
|
||||
iconPathOff: 'attractive',
|
||||
relatedStrategyPart: 'Situation',
|
||||
rawRadius: 8,
|
||||
targetRadius: 0,
|
||||
currentRadius: 0,
|
||||
angle: 0
|
||||
}]
|
||||
break
|
||||
}
|
||||
case 'Strategy Exit Event': {
|
||||
menuItemsInitialValues = [
|
||||
{
|
||||
action: 'Pin / Unpin',
|
||||
actionFunction: floatingObject.pinToggle,
|
||||
currentStatus: false,
|
||||
label: undefined,
|
||||
visible: false,
|
||||
iconPathOn: 'target',
|
||||
iconPathOff: 'security',
|
||||
rawRadius: 8,
|
||||
targetRadius: 0,
|
||||
currentRadius: 0,
|
||||
angle: -135
|
||||
},
|
||||
{
|
||||
action: 'Add Situation',
|
||||
actionFunction: payload.onMenuItemClick,
|
||||
label: 'Add Situation',
|
||||
visible: false,
|
||||
iconPathOn: 'attractive',
|
||||
iconPathOff: 'attractive',
|
||||
relatedStrategyPart: 'Situation',
|
||||
rawRadius: 8,
|
||||
targetRadius: 0,
|
||||
currentRadius: 0,
|
||||
angle: 0
|
||||
}]
|
||||
break
|
||||
}
|
||||
case 'Trade Entry Event': {
|
||||
menuItemsInitialValues = [
|
||||
{
|
||||
action: 'Pin / Unpin',
|
||||
actionFunction: floatingObject.pinToggle,
|
||||
currentStatus: false,
|
||||
label: undefined,
|
||||
visible: false,
|
||||
iconPathOn: 'target',
|
||||
iconPathOff: 'security',
|
||||
rawRadius: 8,
|
||||
targetRadius: 0,
|
||||
currentRadius: 0,
|
||||
angle: -135
|
||||
},
|
||||
{
|
||||
action: 'Add Situation',
|
||||
actionFunction: payload.onMenuItemClick,
|
||||
label: 'Add Situation',
|
||||
visible: false,
|
||||
iconPathOn: 'attractive',
|
||||
iconPathOff: 'attractive',
|
||||
relatedStrategyPart: 'Situation',
|
||||
rawRadius: 8,
|
||||
targetRadius: 0,
|
||||
currentRadius: 0,
|
||||
angle: 0
|
||||
}]
|
||||
break
|
||||
}
|
||||
case 'Stop': {
|
||||
menuItemsInitialValues = [
|
||||
{
|
||||
action: 'Pin / Unpin',
|
||||
actionFunction: floatingObject.pinToggle,
|
||||
currentStatus: false,
|
||||
label: undefined,
|
||||
visible: false,
|
||||
iconPathOn: 'target',
|
||||
iconPathOff: 'security',
|
||||
rawRadius: 8,
|
||||
targetRadius: 0,
|
||||
currentRadius: 0,
|
||||
angle: -135
|
||||
},
|
||||
{
|
||||
action: 'Add Phase',
|
||||
actionFunction: payload.onMenuItemClick,
|
||||
label: 'Add Phase',
|
||||
visible: false,
|
||||
iconPathOn: 'placeholder',
|
||||
iconPathOff: 'placeholder',
|
||||
relatedStrategyPart: 'Phase',
|
||||
rawRadius: 8,
|
||||
targetRadius: 0,
|
||||
currentRadius: 0,
|
||||
angle: 0
|
||||
}]
|
||||
break
|
||||
}
|
||||
case 'Take Profit': {
|
||||
menuItemsInitialValues = [
|
||||
{
|
||||
action: 'Pin / Unpin',
|
||||
actionFunction: floatingObject.pinToggle,
|
||||
currentStatus: false,
|
||||
label: undefined,
|
||||
visible: false,
|
||||
iconPathOn: 'target',
|
||||
iconPathOff: 'security',
|
||||
rawRadius: 8,
|
||||
targetRadius: 0,
|
||||
currentRadius: 0,
|
||||
angle: -135
|
||||
},
|
||||
{
|
||||
action: 'Add Phase',
|
||||
actionFunction: payload.onMenuItemClick,
|
||||
label: 'Add Phase',
|
||||
visible: false,
|
||||
iconPathOn: 'placeholder',
|
||||
iconPathOff: 'placeholder',
|
||||
relatedStrategyPart: 'Phase',
|
||||
rawRadius: 8,
|
||||
targetRadius: 0,
|
||||
currentRadius: 0,
|
||||
angle: 0
|
||||
}]
|
||||
break
|
||||
}
|
||||
case 'Phase': {
|
||||
strategyPart.codeEditor = newCodeEditor()
|
||||
strategyPart.codeEditor.isVisibleFunction = strategyPart.isVisibleFunction
|
||||
strategyPart.codeEditor.initialize()
|
||||
strategyPart.codeEditor.container.connectToParent(strategyPart.container, false, false, true, true, false, false, false, false)
|
||||
|
||||
menuItemsInitialValues = [
|
||||
{
|
||||
action: 'Pin / Unpin',
|
||||
actionFunction: floatingObject.pinToggle,
|
||||
currentStatus: false,
|
||||
label: undefined,
|
||||
visible: false,
|
||||
iconPathOn: 'target',
|
||||
iconPathOff: 'security',
|
||||
rawRadius: 8,
|
||||
targetRadius: 0,
|
||||
currentRadius: 0,
|
||||
angle: -135
|
||||
},
|
||||
{
|
||||
action: 'Edit Code',
|
||||
actionFunction: strategyPart.codeEditor.activate,
|
||||
label: 'Edit Code',
|
||||
visible: false,
|
||||
iconPathOn: 'html',
|
||||
iconPathOff: 'html',
|
||||
rawRadius: 8,
|
||||
targetRadius: 0,
|
||||
currentRadius: 0,
|
||||
angle: 40
|
||||
},
|
||||
{
|
||||
action: 'Add Situation',
|
||||
actionFunction: payload.onMenuItemClick,
|
||||
label: 'Add Situation',
|
||||
visible: false,
|
||||
iconPathOn: 'attractive',
|
||||
iconPathOff: 'attractive',
|
||||
relatedStrategyPart: 'Situation',
|
||||
rawRadius: 8,
|
||||
targetRadius: 0,
|
||||
currentRadius: 0,
|
||||
angle: 0
|
||||
},
|
||||
{
|
||||
action: 'Delete Phase',
|
||||
actionFunction: payload.onMenuItemClick,
|
||||
label: 'Delete This Phase',
|
||||
visible: false,
|
||||
iconPathOn: 'trash',
|
||||
iconPathOff: 'trash',
|
||||
rawRadius: 8,
|
||||
targetRadius: 0,
|
||||
currentRadius: 0,
|
||||
angle: -40
|
||||
}]
|
||||
break
|
||||
}
|
||||
case 'Situation': {
|
||||
menuItemsInitialValues = [
|
||||
{
|
||||
action: 'Pin / Unpin',
|
||||
actionFunction: floatingObject.pinToggle,
|
||||
currentStatus: false,
|
||||
label: undefined,
|
||||
visible: false,
|
||||
iconPathOn: 'target',
|
||||
iconPathOff: 'security',
|
||||
rawRadius: 8,
|
||||
targetRadius: 0,
|
||||
currentRadius: 0,
|
||||
angle: -135
|
||||
},
|
||||
{
|
||||
action: 'Add Condition',
|
||||
actionFunction: payload.onMenuItemClick,
|
||||
label: 'Add Condition',
|
||||
visible: false,
|
||||
iconPathOn: 'testing',
|
||||
iconPathOff: 'testing',
|
||||
relatedStrategyPart: 'Condition',
|
||||
rawRadius: 8,
|
||||
targetRadius: 0,
|
||||
currentRadius: 0,
|
||||
angle: 20
|
||||
},
|
||||
{
|
||||
action: 'Delete Situation',
|
||||
actionFunction: payload.onMenuItemClick,
|
||||
label: 'Delete This Situation',
|
||||
visible: false,
|
||||
iconPathOn: 'trash',
|
||||
iconPathOff: 'trash',
|
||||
rawRadius: 8,
|
||||
targetRadius: 0,
|
||||
currentRadius: 0,
|
||||
angle: -20
|
||||
}]
|
||||
break
|
||||
}
|
||||
case 'Condition': {
|
||||
strategyPart.codeEditor = newCodeEditor()
|
||||
strategyPart.codeEditor.isVisibleFunction = strategyPart.isVisibleFunction
|
||||
strategyPart.codeEditor.initialize()
|
||||
strategyPart.codeEditor.container.connectToParent(strategyPart.container, false, false, true, true, false, false, false, false)
|
||||
|
||||
menuItemsInitialValues = [
|
||||
{
|
||||
action: 'Pin / Unpin',
|
||||
actionFunction: floatingObject.pinToggle,
|
||||
currentStatus: false,
|
||||
label: undefined,
|
||||
visible: false,
|
||||
iconPathOn: 'target',
|
||||
iconPathOff: 'security',
|
||||
rawRadius: 8,
|
||||
targetRadius: 0,
|
||||
currentRadius: 0,
|
||||
angle: -135
|
||||
},
|
||||
{
|
||||
action: 'Edit Code',
|
||||
actionFunction: strategyPart.codeEditor.activate,
|
||||
label: 'Edit Code',
|
||||
visible: false,
|
||||
iconPathOn: 'html',
|
||||
iconPathOff: 'html',
|
||||
rawRadius: 8,
|
||||
targetRadius: 0,
|
||||
currentRadius: 0,
|
||||
angle: 20
|
||||
},
|
||||
{
|
||||
action: 'Delete Condition',
|
||||
actionFunction: payload.onMenuItemClick,
|
||||
label: 'Delete This Condition',
|
||||
visible: false,
|
||||
iconPathOn: 'trash',
|
||||
iconPathOff: 'trash',
|
||||
rawRadius: 8,
|
||||
targetRadius: 0,
|
||||
currentRadius: 0,
|
||||
angle: -20
|
||||
}]
|
||||
break
|
||||
}
|
||||
default: {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] getMenuItemsInitialValues -> Part Type not Recognized -> type = ' + payload.node.type) }
|
||||
}
|
||||
}
|
||||
|
||||
return menuItemsInitialValues
|
||||
}
|
||||
|
||||
function setFloatingObjectBasicProperties (floatingObject, payload) {
|
||||
const FRICTION = 0.97
|
||||
|
||||
switch (payload.node.type) {
|
||||
case 'Trading System': {
|
||||
level_0()
|
||||
break
|
||||
}
|
||||
case 'Strategy': {
|
||||
level_1()
|
||||
break
|
||||
}
|
||||
case 'Strategy Entry Event': {
|
||||
level_2()
|
||||
break
|
||||
}
|
||||
case 'Strategy Exit Event': {
|
||||
level_2()
|
||||
break
|
||||
}
|
||||
case 'Trade Entry Event': {
|
||||
level_2()
|
||||
break
|
||||
}
|
||||
case 'Trade Exit Event': {
|
||||
level_2()
|
||||
break
|
||||
}
|
||||
case 'Stop': {
|
||||
level_2()
|
||||
break
|
||||
}
|
||||
case 'Take Profit': {
|
||||
level_2()
|
||||
break
|
||||
}
|
||||
case 'Phase': {
|
||||
level_3()
|
||||
break
|
||||
}
|
||||
case 'Situation': {
|
||||
level_4()
|
||||
break
|
||||
}
|
||||
case 'Condition': {
|
||||
level_5()
|
||||
break
|
||||
}
|
||||
default: {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> Part Type not Recognized -> type = ' + payload.node.type) }
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
function level_0 () {
|
||||
floatingObject.friction = 0.93
|
||||
|
||||
floatingObject.initializeMass(500)
|
||||
floatingObject.initializeRadius(45)
|
||||
floatingObject.initializeImageSize(80)
|
||||
floatingObject.initializeFontSize(10)
|
||||
|
||||
floatingObject.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', 1)'
|
||||
}
|
||||
|
||||
function level_1 () {
|
||||
floatingObject.friction = 0.94
|
||||
|
||||
floatingObject.initializeMass(250)
|
||||
floatingObject.initializeRadius(45)
|
||||
floatingObject.initializeImageSize(80)
|
||||
floatingObject.initializeFontSize(10)
|
||||
|
||||
floatingObject.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', 1)'
|
||||
}
|
||||
|
||||
function level_2 () {
|
||||
floatingObject.friction = FRICTION
|
||||
|
||||
floatingObject.initializeMass(50)
|
||||
floatingObject.initializeRadius(40)
|
||||
floatingObject.initializeImageSize(70)
|
||||
floatingObject.initializeFontSize(10)
|
||||
|
||||
floatingObject.fillStyle = 'rgba(' + UI_COLOR.GREEN + ', 1)'
|
||||
}
|
||||
|
||||
function level_3 () {
|
||||
floatingObject.friction = FRICTION
|
||||
|
||||
floatingObject.initializeMass(10)
|
||||
floatingObject.initializeRadius(35)
|
||||
floatingObject.initializeImageSize(60)
|
||||
floatingObject.initializeFontSize(10)
|
||||
|
||||
floatingObject.fillStyle = 'rgba(' + UI_COLOR.RUSTED_RED + ', 1)'
|
||||
}
|
||||
|
||||
function level_4 () {
|
||||
floatingObject.friction = FRICTION
|
||||
|
||||
floatingObject.initializeMass(10)
|
||||
floatingObject.initializeRadius(30)
|
||||
floatingObject.initializeImageSize(50)
|
||||
floatingObject.initializeFontSize(10)
|
||||
|
||||
floatingObject.fillStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', 1)'
|
||||
}
|
||||
|
||||
function level_5 () {
|
||||
floatingObject.friction = FRICTION
|
||||
|
||||
floatingObject.initializeMass(10)
|
||||
floatingObject.initializeRadius(25)
|
||||
floatingObject.initializeImageSize(30)
|
||||
floatingObject.initializeFontSize(10)
|
||||
|
||||
floatingObject.fillStyle = 'rgba(' + UI_COLOR.RED + ', 1)'
|
||||
}
|
||||
|
||||
floatingObject.labelStrokeStyle = 'rgba(' + UI_COLOR.WHITE + ', 1)'
|
||||
}
|
||||
|
||||
function destroyStrategyPart (payload) {
|
||||
floatingLayer.removeFloatingObject(payload.floatingObject.handle)
|
||||
|
||||
payload.floatingObject.finalize()
|
||||
payload.floatingObject = undefined
|
||||
|
||||
payload.uiObject.finalize()
|
||||
payload.uiObject = undefined
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,260 @@
|
||||
|
||||
function newStrategyPartTitle () {
|
||||
const MODULE_NAME = 'Strategy Part Title'
|
||||
const ERROR_LOG = true
|
||||
|
||||
const logger = newWebDebugLog()
|
||||
logger.fileName = MODULE_NAME
|
||||
|
||||
let thisObject = {
|
||||
isVisibleFunction: undefined,
|
||||
allwaysVisible: undefined,
|
||||
editMode: undefined,
|
||||
container: undefined,
|
||||
payload: undefined,
|
||||
enterEditMode: enterEditMode,
|
||||
exitEditMode: exitEditMode,
|
||||
physics: physics,
|
||||
draw: draw,
|
||||
getContainer: getContainer,
|
||||
finalize: finalize,
|
||||
initialize: initialize
|
||||
}
|
||||
|
||||
thisObject.container = newContainer()
|
||||
thisObject.container.initialize(MODULE_NAME)
|
||||
thisObject.container.isClickeable = true
|
||||
thisObject.container.isDraggeable = false
|
||||
thisObject.container.frame.radius = 0
|
||||
|
||||
let selfFocusEventSubscriptionId
|
||||
let selfNotFocuskEventSubscriptionId
|
||||
let selfMouseClickEventSubscriptionId
|
||||
|
||||
return thisObject
|
||||
|
||||
function finalize () {
|
||||
thisObject.container.eventHandler.stopListening(selfFocusEventSubscriptionId)
|
||||
thisObject.container.eventHandler.stopListening(selfNotFocuskEventSubscriptionId)
|
||||
thisObject.container.eventHandler.stopListening(selfMouseClickEventSubscriptionId)
|
||||
|
||||
thisObject.container.finalize()
|
||||
thisObject.container = undefined
|
||||
thisObject.payload = undefined
|
||||
thisObject.isVisibleFunction = undefined
|
||||
}
|
||||
|
||||
function initialize (payload) {
|
||||
thisObject.payload = payload
|
||||
|
||||
switch (payload.node.type) {
|
||||
case 'Trading System': {
|
||||
break
|
||||
}
|
||||
case 'Strategy': {
|
||||
thisObject.allwaysVisible = true
|
||||
break
|
||||
}
|
||||
case 'Strategy Entry Event': {
|
||||
break
|
||||
}
|
||||
case 'Strategy Exit Event': {
|
||||
break
|
||||
}
|
||||
case 'Trade Entry Event': {
|
||||
break
|
||||
}
|
||||
case 'Stop': {
|
||||
break
|
||||
}
|
||||
case 'Take Profit': {
|
||||
break
|
||||
}
|
||||
case 'Phase': {
|
||||
break
|
||||
}
|
||||
case 'Situation': {
|
||||
break
|
||||
}
|
||||
case 'Condition': {
|
||||
break
|
||||
}
|
||||
default: {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> Part Type not Recognized -> type = ' + payload.node.type) }
|
||||
}
|
||||
}
|
||||
|
||||
selfFocusEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onFocus', onFocus)
|
||||
selfNotFocuskEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onNotFocus', onNotFocus)
|
||||
selfMouseClickEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick)
|
||||
}
|
||||
|
||||
function getContainer (point) {
|
||||
let container
|
||||
|
||||
if (thisObject.editMode === true) {
|
||||
if (point.x === VERY_LARGE_NUMBER) {
|
||||
/* The the mouse leaves the canvas, and event of mouse over with a ridiculous coordinate is triggered so that
|
||||
anyone can react. In our case, this object has an html input element that is not part of the canvas, so the event is
|
||||
triggered. We compensate recognizing this coordinate and returning our container. */
|
||||
return thisObject.container
|
||||
}
|
||||
}
|
||||
if (thisObject.container.frame.isThisPointHere(point, true) === true) {
|
||||
return thisObject.container
|
||||
} else {
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
function physics () {
|
||||
let title = trimTitle(thisObject.payload.title)
|
||||
|
||||
const FRAME_HEIGHT = 25
|
||||
const FRAME_WIDTH = title.length / 2 * thisObject.payload.floatingObject.currentFontSize * FONT_ASPECT_RATIO * 1.2 * 2
|
||||
thisObject.container.frame.position.x = 0 - FRAME_WIDTH / 2
|
||||
thisObject.container.frame.position.y = 0 - thisObject.container.frame.radius * 1 / 2 - thisObject.payload.floatingObject.currentFontSize * FONT_ASPECT_RATIO - 10 - FRAME_HEIGHT
|
||||
|
||||
thisObject.container.frame.width = FRAME_WIDTH
|
||||
thisObject.container.frame.height = FRAME_HEIGHT
|
||||
|
||||
if (thisObject.editMode === true) {
|
||||
let inputPosition = {
|
||||
x: 0,
|
||||
y: 0 + window.canvasApp.topMargin
|
||||
}
|
||||
|
||||
inputPosition = thisObject.container.frame.frameThisPoint(inputPosition)
|
||||
|
||||
if (inputPosition.y < window.canvasApp.topMargin) { exitEditMode() }
|
||||
|
||||
let inputDiv = document.getElementById('inputDiv')
|
||||
inputDiv.style = 'position:absolute; top:' + inputPosition.y + 'px; left:' + inputPosition.x + 'px; z-index:1; '
|
||||
}
|
||||
}
|
||||
|
||||
function onFocus () {
|
||||
thisObject.isOnFocus = true
|
||||
}
|
||||
|
||||
function onNotFocus () {
|
||||
thisObject.isOnFocus = false
|
||||
exitEditMode()
|
||||
}
|
||||
|
||||
function onMouseClick (event) {
|
||||
let checkPoint = {
|
||||
x: 0,
|
||||
y: 0
|
||||
}
|
||||
checkPoint = thisObject.container.frame.frameThisPoint(checkPoint)
|
||||
|
||||
if (thisObject.isVisibleFunction(checkPoint) === true) {
|
||||
enterEditMode()
|
||||
}
|
||||
}
|
||||
|
||||
function exitEditMode () {
|
||||
if (thisObject.editMode === true) {
|
||||
thisObject.editMode = false
|
||||
let input = document.getElementById('input')
|
||||
input.style.display = 'none'
|
||||
if (input.value.length > 2) {
|
||||
thisObject.payload.title = input.value
|
||||
thisObject.payload.node.name = input.value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function enterEditMode () {
|
||||
const WIDTH = thisObject.container.frame.width
|
||||
const HEIGHT = thisObject.container.frame.height
|
||||
let fontSize = thisObject.payload.floatingObject.currentFontSize
|
||||
|
||||
thisObject.editMode = true
|
||||
let input = document.getElementById('input')
|
||||
input.value = thisObject.payload.title
|
||||
|
||||
let backgroundColor = '0, 0, 0'
|
||||
if (thisObject.payload.uiObject.codeEditor !== undefined) {
|
||||
if (thisObject.payload.uiObject.codeEditor.visible === true) {
|
||||
backgroundColor = '204, 88, 53'
|
||||
}
|
||||
}
|
||||
|
||||
input.style = 'resize: none; border: none; outline: none; box-shadow: none; overflow:hidden; font-family: Saira; font-size: ' + fontSize + 'px; background-color: rgb(' + backgroundColor + ');color:rgb(255, 255, 255); width: ' + WIDTH + 'px; height: ' + HEIGHT + 'px'
|
||||
input.style.display = 'block'
|
||||
input.focus()
|
||||
}
|
||||
|
||||
function draw () {
|
||||
if (thisObject.isOnFocus === true || thisObject.allwaysVisible === true) {
|
||||
if (thisObject.payload.uiObject.codeEditor !== undefined) {
|
||||
if (thisObject.payload.uiObject.codeEditor.visible !== true) {
|
||||
drawTitleBackground()
|
||||
}
|
||||
} else {
|
||||
drawTitleBackground()
|
||||
}
|
||||
|
||||
drawText()
|
||||
}
|
||||
}
|
||||
|
||||
function drawTitleBackground () {
|
||||
if (thisObject.editMode !== true) {
|
||||
let params = {
|
||||
cornerRadius: 3,
|
||||
lineWidth: 0.1,
|
||||
container: thisObject.container,
|
||||
borderColor: UI_COLOR.BLACK,
|
||||
backgroundColor: UI_COLOR.BLACK,
|
||||
castShadow: false,
|
||||
opacity: 0.25
|
||||
}
|
||||
|
||||
roundedCornersBackground(params)
|
||||
}
|
||||
}
|
||||
|
||||
function drawText () {
|
||||
if (thisObject.editMode !== true) {
|
||||
let radius = thisObject.container.frame.radius
|
||||
let labelPoint
|
||||
let fontSize = thisObject.payload.floatingObject.currentFontSize
|
||||
let label
|
||||
|
||||
if (radius > 6 && (thisObject.isOnFocus === true || thisObject.allwaysVisible === true)) {
|
||||
browserCanvasContext.strokeStyle = thisObject.payload.floatingObject.labelStrokeStyle
|
||||
|
||||
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
|
||||
|
||||
label = thisObject.payload.title
|
||||
|
||||
if (label !== undefined) {
|
||||
label = trimTitle(label)
|
||||
|
||||
labelPoint = {
|
||||
x: 0,
|
||||
y: thisObject.container.frame.height * 0.8
|
||||
}
|
||||
|
||||
labelPoint = thisObject.container.frame.frameThisPoint(labelPoint)
|
||||
|
||||
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
|
||||
browserCanvasContext.fillStyle = thisObject.payload.floatingObject.labelStrokeStyle
|
||||
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function trimTitle (title) {
|
||||
const MAX_LABEL_LENGTH = 25
|
||||
if (title.length > MAX_LABEL_LENGTH) {
|
||||
title = title.substring(0, MAX_LABEL_LENGTH) + '...'
|
||||
}
|
||||
return title
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,57 +1,63 @@
|
||||
|
||||
function newFrame () {
|
||||
const PANEL_CORNERS_RADIOUS = 5
|
||||
const TITLE_BAR_HEIGHT = 14 // this must be grater than radius
|
||||
|
||||
let frame = {
|
||||
function newFrame () {
|
||||
const PANEL_CORNERS_RADIUS = 5
|
||||
const TITLE_BAR_HEIGHT = 15 // this must be grater than radius
|
||||
|
||||
let thisObject = {
|
||||
type: 'Rectangle',
|
||||
containerName: '', // This is for debugging purposes only.
|
||||
parentFrame: undefined, // Here we store the parent cointainer zoom object.
|
||||
radius: 0,
|
||||
position: undefined,
|
||||
container: undefined,
|
||||
width: browserCanvas.width,
|
||||
height: browserCanvas.height,
|
||||
position: undefined,
|
||||
getBodyHeight: getBodyHeight,
|
||||
draw: draw,
|
||||
container: undefined,
|
||||
fitIntoFrame: fitIntoFrame,
|
||||
frameThisPoint: frameThisPoint, // This function changes the actual frame coordinate system to the screen coordinate system.
|
||||
unframeThisPoint: unframeThisPoint,
|
||||
fitIntoFrame: fitIntoFrame,
|
||||
isThisPointHere: isThisPointHere, // This function return true is the point received as parameter lives within this frame.
|
||||
isThisScreenPointHere: isThisScreenPointHere,
|
||||
isInViewPort: isInViewPort,
|
||||
canYouMoveHere: canYouMoveHere,
|
||||
canYouZoomHere: canYouZoomHere,
|
||||
initialize: initialize
|
||||
}
|
||||
|
||||
return frame
|
||||
return thisObject
|
||||
|
||||
function initialize () {
|
||||
var position = {
|
||||
function initialize (pType) {
|
||||
if (pType !== undefined) { thisObject.type = pType }
|
||||
|
||||
let position = {
|
||||
x: 0,
|
||||
y: 0
|
||||
}
|
||||
|
||||
this.position = position
|
||||
thisObject.position = position
|
||||
}
|
||||
|
||||
function getBodyHeight () {
|
||||
return frame.height - TITLE_BAR_HEIGHT
|
||||
return thisObject.height - TITLE_BAR_HEIGHT
|
||||
}
|
||||
|
||||
function isInViewPort () {
|
||||
/* This function is usefull to know if the object who has this frame is currently appearing at least in part at the viewPort */
|
||||
|
||||
point1 = {
|
||||
x: 0,
|
||||
y: 0
|
||||
}
|
||||
|
||||
point3 = {
|
||||
x: frame.width,
|
||||
y: frame.height
|
||||
x: thisObject.width,
|
||||
y: thisObject.height
|
||||
}
|
||||
|
||||
/* Now the transformations. */
|
||||
/* Now the transformations. */
|
||||
|
||||
point1 = transformThisPoint(point1, frame.container)
|
||||
point3 = transformThisPoint(point3, frame.container)
|
||||
point1 = transformThisPoint(point1, thisObject.container)
|
||||
point3 = transformThisPoint(point3, thisObject.container)
|
||||
|
||||
if (point1.x < viewPort.visibleArea.topRight.x && point1.y < viewPort.visibleArea.bottomRight.y && point3.x > viewPort.visibleArea.bottomLeft.x && point3.y > viewPort.visibleArea.topLeft.y) {
|
||||
return true
|
||||
@@ -60,19 +66,81 @@ function newFrame () {
|
||||
}
|
||||
}
|
||||
|
||||
function frameThisPoint (point) {
|
||||
/* We need not to modify the point received, so me make a copy of it. */
|
||||
|
||||
let checkPoint = {
|
||||
x: point.x,
|
||||
y: point.y
|
||||
}
|
||||
|
||||
let parentPoint = {
|
||||
x: 0,
|
||||
y: 0
|
||||
}
|
||||
|
||||
let returnPoint = {
|
||||
x: 0,
|
||||
y: 0
|
||||
}
|
||||
|
||||
if (thisObject.parentFrame !== undefined) {
|
||||
parentPoint = thisObject.parentFrame.frameThisPoint(checkPoint)
|
||||
|
||||
returnPoint.x = parentPoint.x + thisObject.position.x
|
||||
returnPoint.y = parentPoint.y + thisObject.position.y
|
||||
} else {
|
||||
returnPoint.x = checkPoint.x + thisObject.position.x
|
||||
returnPoint.y = checkPoint.y + thisObject.position.y
|
||||
}
|
||||
|
||||
return returnPoint
|
||||
}
|
||||
|
||||
function unframeThisPoint (point) {
|
||||
/* We need not to modify the point received, so me make a copy of it. */
|
||||
|
||||
let checkPoint = {
|
||||
x: point.x,
|
||||
y: point.y
|
||||
}
|
||||
|
||||
let parentPoint = {
|
||||
x: 0,
|
||||
y: 0
|
||||
}
|
||||
|
||||
let returnPoint = {
|
||||
x: 0,
|
||||
y: 0
|
||||
}
|
||||
|
||||
if (thisObject.parentFrame !== undefined) {
|
||||
parentPoint = thisObject.parentFrame.unframeThisPoint(checkPoint)
|
||||
|
||||
returnPoint.x = parentPoint.x - thisObject.position.x
|
||||
returnPoint.y = parentPoint.y - thisObject.position.y
|
||||
} else {
|
||||
returnPoint.x = checkPoint.x - thisObject.position.x
|
||||
returnPoint.y = checkPoint.y - thisObject.position.y
|
||||
}
|
||||
|
||||
return returnPoint
|
||||
}
|
||||
|
||||
function fitIntoFrame (point) {
|
||||
/* Here we check the boundaries of the resulting points, so they dont go out of the visible area. */
|
||||
|
||||
if (point.x > frame.width) {
|
||||
point.x = frame.width
|
||||
if (point.x > thisObject.width) {
|
||||
point.x = thisObject.width
|
||||
}
|
||||
|
||||
if (point.x < 0) {
|
||||
point.x = 0
|
||||
}
|
||||
|
||||
if (point.y > frame.height) {
|
||||
point.y = frame.height
|
||||
if (point.y > thisObject.height) {
|
||||
point.y = thisObject.height
|
||||
}
|
||||
|
||||
if (point.y < 0) {
|
||||
@@ -82,158 +150,71 @@ function newFrame () {
|
||||
return point
|
||||
}
|
||||
|
||||
function frameThisPoint (point) {
|
||||
if (this.parentFrame !== undefined) {
|
||||
point = this.parentFrame.frameThisPoint(point)
|
||||
}
|
||||
|
||||
point.x = point.x + frame.position.x
|
||||
point.y = point.y + frame.position.y
|
||||
|
||||
return point
|
||||
}
|
||||
|
||||
function unframeThisPoint (point) {
|
||||
if (this.parentFrame !== undefined) {
|
||||
point = this.parentFrame.unframeThisPoint(point)
|
||||
}
|
||||
|
||||
point.x = point.x - this.position.x
|
||||
point.y = point.y - this.position.y
|
||||
|
||||
return point
|
||||
}
|
||||
|
||||
function canYouMoveHere (tempDisplacement) {
|
||||
/*
|
||||
/*
|
||||
|
||||
The current frame has a position and a displacement. We need to check that none of the boundaries points of the frame fall outside of its container frame.
|
||||
First we apply the theoreticall displacement.
|
||||
The current frame has a position and a displacement. We need to check that none of the boundaries points of the frame fall outside of its container frame.
|
||||
First we apply the theoreticall displacement.
|
||||
|
||||
*/
|
||||
*/
|
||||
|
||||
point1 = {
|
||||
x: this.position.x,
|
||||
y: this.position.y
|
||||
x: thisObject.position.x,
|
||||
y: thisObject.position.y
|
||||
}
|
||||
|
||||
point2 = {
|
||||
x: this.position.x + this.width,
|
||||
y: this.position.y
|
||||
x: thisObject.position.x + thisObject.width,
|
||||
y: thisObject.position.y
|
||||
}
|
||||
|
||||
point3 = {
|
||||
x: this.position.x + this.width,
|
||||
y: this.position.y + this.height
|
||||
x: thisObject.position.x + thisObject.width,
|
||||
y: thisObject.position.y + thisObject.height
|
||||
}
|
||||
|
||||
point4 = {
|
||||
x: this.position.x,
|
||||
y: this.position.y + this.height
|
||||
x: thisObject.position.x,
|
||||
y: thisObject.position.y + thisObject.height
|
||||
}
|
||||
|
||||
/* Now the transformations. */
|
||||
/* Now the transformations. */
|
||||
|
||||
if (this.parentFrame !== undefined) {
|
||||
// If there is not a parent then there is no point to check bounderies.
|
||||
if (thisObject.parentFrame !== undefined) {
|
||||
// If there is not a parent then there is no point to check bounderies.
|
||||
|
||||
point1 = this.parentFrame.frameThisPoint(point1)
|
||||
point2 = this.parentFrame.frameThisPoint(point2)
|
||||
point3 = this.parentFrame.frameThisPoint(point3)
|
||||
point4 = this.parentFrame.frameThisPoint(point4)
|
||||
point1 = thisObject.parentFrame.frameThisPoint(point1)
|
||||
point2 = thisObject.parentFrame.frameThisPoint(point2)
|
||||
point3 = thisObject.parentFrame.frameThisPoint(point3)
|
||||
point4 = thisObject.parentFrame.frameThisPoint(point4)
|
||||
|
||||
/* We apply the temporary displacement. */
|
||||
/* We apply the temporary displacement. */
|
||||
|
||||
point1 = tempDisplacement.displaceThisPoint(point1)
|
||||
point2 = tempDisplacement.displaceThisPoint(point2)
|
||||
point3 = tempDisplacement.displaceThisPoint(point3)
|
||||
point4 = tempDisplacement.displaceThisPoint(point4)
|
||||
|
||||
/* We add the actual displacement. */
|
||||
/* We add the actual displacement. */
|
||||
|
||||
point1 = this.container.displacement.displaceThisPoint(point1)
|
||||
point2 = this.container.displacement.displaceThisPoint(point2)
|
||||
point3 = this.container.displacement.displaceThisPoint(point3)
|
||||
point4 = this.container.displacement.displaceThisPoint(point4)
|
||||
point1 = thisObject.container.displacement.displaceThisPoint(point1)
|
||||
point2 = thisObject.container.displacement.displaceThisPoint(point2)
|
||||
point3 = thisObject.container.displacement.displaceThisPoint(point3)
|
||||
point4 = thisObject.container.displacement.displaceThisPoint(point4)
|
||||
|
||||
if (this.parentFrame.isThisPointHere(point1) === false) {
|
||||
if (thisObject.parentFrame.isThisPointHere(point1) === false) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (this.parentFrame.isThisPointHere(point2) === false) {
|
||||
if (thisObject.parentFrame.isThisPointHere(point2) === false) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (this.parentFrame.isThisPointHere(point3) === false) {
|
||||
if (thisObject.parentFrame.isThisPointHere(point3) === false) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (this.parentFrame.isThisPointHere(point4) === false) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
function canYouZoomHere (tempZoom) {
|
||||
point1 = {
|
||||
x: this.position.x,
|
||||
y: this.position.y
|
||||
}
|
||||
|
||||
point2 = {
|
||||
x: this.position.x + this.width,
|
||||
y: this.position.y
|
||||
}
|
||||
|
||||
point3 = {
|
||||
x: this.position.x + this.width,
|
||||
y: this.position.y + this.height
|
||||
}
|
||||
|
||||
point4 = {
|
||||
x: this.position.x,
|
||||
y: this.position.y + this.height
|
||||
}
|
||||
|
||||
/* Now the transformations. */
|
||||
|
||||
if (this.parentFrame !== undefined) {
|
||||
// If there is not a parent then there is no point to check bounderies.
|
||||
|
||||
point1 = this.parentFrame.frameThisPoint(point1)
|
||||
point2 = this.parentFrame.frameThisPoint(point2)
|
||||
point3 = this.parentFrame.frameThisPoint(point3)
|
||||
point4 = this.parentFrame.frameThisPoint(point4)
|
||||
|
||||
/* We add the actual displacement. */
|
||||
|
||||
point1 = this.container.displacement.displaceThisPoint(point1)
|
||||
point2 = this.container.displacement.displaceThisPoint(point2)
|
||||
point3 = this.container.displacement.displaceThisPoint(point3)
|
||||
point4 = this.container.displacement.displaceThisPoint(point4)
|
||||
|
||||
/* We temp zoom. */
|
||||
|
||||
point1 = tempZoom.zoomThisPoint(point1)
|
||||
point2 = tempZoom.zoomThisPoint(point2)
|
||||
point3 = tempZoom.zoomThisPoint(point3)
|
||||
point4 = tempZoom.zoomThisPoint(point4)
|
||||
|
||||
if (this.parentFrame.isThisPointHere(point1) === false) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (this.parentFrame.isThisPointHere(point2) === false) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (this.parentFrame.isThisPointHere(point3) === false) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (this.parentFrame.isThisPointHere(point4) === false) {
|
||||
if (thisObject.parentFrame.isThisPointHere(point4) === false) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -242,73 +223,107 @@ function newFrame () {
|
||||
}
|
||||
|
||||
function isThisPointHere (point, outsideViewPort, dontTransform) {
|
||||
// The second parameter is usefull when you want to check a point that you already know is outside the viewport.
|
||||
// The second parameter is usefull when you want to check a point that you already know is outside the viewport.
|
||||
|
||||
/* We need not to modify the point received, so me make a copy of it. */
|
||||
/* We need not to modify the point received, so me make a copy of it. */
|
||||
|
||||
var checkPoint = {
|
||||
let checkPoint = {
|
||||
x: point.x,
|
||||
y: point.y
|
||||
}
|
||||
|
||||
/* The point received is on the screen coordinates system, which already has zoom and displacement applied. We need to remove the zoom and displacement
|
||||
in order to have the point on the containers coordinate system and be able to compare it with its dimmensions. */
|
||||
/* The point received is on the screen coordinates system, which already has zoom and displacement applied. We need to remove the zoom and displacement
|
||||
in order to have the point on the containers coordinate system and be able to compare it with its dimmensions. */
|
||||
if (dontTransform === false || dontTransform === undefined) {
|
||||
if (outsideViewPort === true) {
|
||||
checkPoint = this.container.displacement.undisplaceThisPoint(checkPoint)
|
||||
checkPoint = this.container.frame.unframeThisPoint(checkPoint)
|
||||
checkPoint = thisObject.container.displacement.undisplaceThisPoint(checkPoint)
|
||||
checkPoint = thisObject.container.frame.unframeThisPoint(checkPoint)
|
||||
} else {
|
||||
checkPoint = unTransformThisPoint(checkPoint, frame.container)
|
||||
checkPoint = unTransformThisPoint(checkPoint, thisObject.container)
|
||||
}
|
||||
}
|
||||
|
||||
/* Now we check if the resulting point is whin the current Frame. */
|
||||
/* Now we check if the resulting point is whin the current Frame. */
|
||||
|
||||
if (checkPoint.x < 0 || checkPoint.y < 0 || checkPoint.x > frame.width || checkPoint.y > frame.height) {
|
||||
/* The point received is not in this frame */
|
||||
if (thisObject.type === 'Circle') {
|
||||
let distance = Math.sqrt(Math.pow(thisObject.position.x - point.x, 2) + Math.pow(thisObject.position.y - point.y, 2))
|
||||
|
||||
return false
|
||||
} else {
|
||||
/* The point is within this frame. */
|
||||
if (distance < thisObject.radius) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
if (thisObject.type === 'Rectangle') {
|
||||
if (checkPoint.x < 0 || checkPoint.y < 0 || checkPoint.x > thisObject.width || checkPoint.y > thisObject.height) {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function draw (drawGrid, drawBorders, drawBackground) {
|
||||
function isThisScreenPointHere (point) {
|
||||
let checkPoint = {
|
||||
x: point.x,
|
||||
y: point.y
|
||||
}
|
||||
|
||||
let thisPoint = {
|
||||
x: thisObject.position.x,
|
||||
y: thisObject.position.y
|
||||
}
|
||||
|
||||
thisPoint = thisObject.parentFrame.frameThisPoint(thisPoint)
|
||||
|
||||
/* Now we check if the resulting point is whin the current Frame. */
|
||||
|
||||
if (thisObject.type === 'Circle') {
|
||||
let distance = Math.sqrt(Math.pow(thisPoint.x - checkPoint.x, 2) + Math.pow(thisPoint.y - checkPoint.y, 2))
|
||||
|
||||
if (distance < thisObject.radius) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if (thisObject.type === 'Rectangle') {
|
||||
if (checkPoint.x < 0 || checkPoint.y < 0 || checkPoint.x > thisObject.width || checkPoint.y > thisObject.height) {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function draw (drawGrid, drawBorders, drawBackground, fitFunction) {
|
||||
if (drawBorders === true) {
|
||||
borders()
|
||||
borders(fitFunction)
|
||||
}
|
||||
|
||||
if (drawGrid === true) {
|
||||
grid()
|
||||
grid(fitFunction)
|
||||
}
|
||||
|
||||
if (drawBackground === true) {
|
||||
background()
|
||||
background(fitFunction)
|
||||
}
|
||||
}
|
||||
|
||||
function background () {
|
||||
borderPoint1 = {
|
||||
x: PANEL_CORNERS_RADIOUS,
|
||||
y: PANEL_CORNERS_RADIOUS
|
||||
function background (fitFunction) {
|
||||
let params = {
|
||||
cornerRadius: 5,
|
||||
lineWidth: 0.1,
|
||||
opacity: 0.75,
|
||||
container: thisObject.container,
|
||||
borderColor: UI_COLOR.DARK,
|
||||
backgroundColor: UI_COLOR.WHITE,
|
||||
fitFunction: fitFunction
|
||||
}
|
||||
|
||||
borderPoint2 = {
|
||||
x: frame.width - PANEL_CORNERS_RADIOUS,
|
||||
y: PANEL_CORNERS_RADIOUS
|
||||
}
|
||||
|
||||
borderPoint3 = {
|
||||
x: frame.width - PANEL_CORNERS_RADIOUS,
|
||||
y: frame.height - PANEL_CORNERS_RADIOUS
|
||||
}
|
||||
|
||||
borderPoint4 = {
|
||||
x: PANEL_CORNERS_RADIOUS,
|
||||
y: frame.height - PANEL_CORNERS_RADIOUS
|
||||
}
|
||||
roundedCornersBackground(params)
|
||||
|
||||
titleBarPoint1 = {
|
||||
x: 0,
|
||||
@@ -316,52 +331,30 @@ function newFrame () {
|
||||
}
|
||||
|
||||
titleBarPoint2 = {
|
||||
x: frame.width,
|
||||
x: thisObject.width,
|
||||
y: TITLE_BAR_HEIGHT
|
||||
}
|
||||
|
||||
/* Now the transformations. */
|
||||
|
||||
borderPoint1 = frameThisPoint(borderPoint1)
|
||||
borderPoint2 = frameThisPoint(borderPoint2)
|
||||
borderPoint3 = frameThisPoint(borderPoint3)
|
||||
borderPoint4 = frameThisPoint(borderPoint4)
|
||||
/* Now the transformations. */
|
||||
|
||||
titleBarPoint1 = frameThisPoint(titleBarPoint1)
|
||||
titleBarPoint2 = frameThisPoint(titleBarPoint2)
|
||||
|
||||
/* We paint the panel background first */
|
||||
if (fitFunction !== undefined) {
|
||||
titleBarPoint1 = fitFunction(titleBarPoint1)
|
||||
titleBarPoint2 = fitFunction(titleBarPoint2)
|
||||
}
|
||||
|
||||
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', 0.75)'
|
||||
browserCanvasContext.beginPath()
|
||||
/* We paint the title bar now */
|
||||
|
||||
browserCanvasContext.arc(borderPoint1.x, borderPoint1.y, PANEL_CORNERS_RADIOUS, 1.0 * Math.PI, 1.5 * Math.PI)
|
||||
browserCanvasContext.lineTo(borderPoint2.x, borderPoint2.y - PANEL_CORNERS_RADIOUS)
|
||||
browserCanvasContext.arc(borderPoint2.x, borderPoint2.y, PANEL_CORNERS_RADIOUS, 1.5 * Math.PI, 2.0 * Math.PI)
|
||||
browserCanvasContext.lineTo(borderPoint3.x + PANEL_CORNERS_RADIOUS, borderPoint3.y)
|
||||
browserCanvasContext.arc(borderPoint3.x, borderPoint3.y, PANEL_CORNERS_RADIOUS, 0 * Math.PI, 0.5 * Math.PI)
|
||||
browserCanvasContext.lineTo(borderPoint4.x, borderPoint4.y + PANEL_CORNERS_RADIOUS)
|
||||
browserCanvasContext.arc(borderPoint4.x, borderPoint4.y, PANEL_CORNERS_RADIOUS, 0.5 * Math.PI, 1.0 * Math.PI)
|
||||
browserCanvasContext.lineTo(borderPoint1.x - PANEL_CORNERS_RADIOUS, borderPoint1.y)
|
||||
|
||||
browserCanvasContext.closePath()
|
||||
|
||||
browserCanvasContext.fill()
|
||||
|
||||
browserCanvasContext.lineWidth = 0.1
|
||||
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.MANGANESE_PURPLE + ', 0.75)'
|
||||
browserCanvasContext.stroke()
|
||||
|
||||
/* We paint the title bar now */
|
||||
|
||||
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.DARK + ', 0.75)'
|
||||
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.DARK + ', 1)'
|
||||
browserCanvasContext.beginPath()
|
||||
|
||||
browserCanvasContext.moveTo(titleBarPoint1.x, titleBarPoint1.y)
|
||||
browserCanvasContext.lineTo(borderPoint1.x - PANEL_CORNERS_RADIOUS, borderPoint1.y)
|
||||
browserCanvasContext.arc(borderPoint1.x, borderPoint1.y, PANEL_CORNERS_RADIOUS, 1.0 * Math.PI, 1.5 * Math.PI)
|
||||
browserCanvasContext.lineTo(borderPoint2.x, borderPoint2.y - PANEL_CORNERS_RADIOUS)
|
||||
browserCanvasContext.arc(borderPoint2.x, borderPoint2.y, PANEL_CORNERS_RADIOUS, 1.5 * Math.PI, 2.0 * Math.PI)
|
||||
browserCanvasContext.lineTo(borderPoint1.x - PANEL_CORNERS_RADIUS, borderPoint1.y)
|
||||
browserCanvasContext.arc(borderPoint1.x, borderPoint1.y, PANEL_CORNERS_RADIUS, 1.0 * Math.PI, 1.5 * Math.PI)
|
||||
browserCanvasContext.lineTo(borderPoint2.x, borderPoint2.y - PANEL_CORNERS_RADIUS)
|
||||
browserCanvasContext.arc(borderPoint2.x, borderPoint2.y, PANEL_CORNERS_RADIUS, 1.5 * Math.PI, 2.0 * Math.PI)
|
||||
browserCanvasContext.lineTo(titleBarPoint2.x, titleBarPoint2.y)
|
||||
|
||||
browserCanvasContext.closePath()
|
||||
@@ -371,31 +364,35 @@ function newFrame () {
|
||||
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.MANGANESE_PURPLE + ', 0.75)'
|
||||
browserCanvasContext.stroke()
|
||||
|
||||
/* print the title */
|
||||
/* print the title */
|
||||
|
||||
let labelPoint
|
||||
let fontSize = 10
|
||||
|
||||
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.SECONDARY + ' Saira'
|
||||
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
|
||||
|
||||
let label = frame.containerName
|
||||
let label = thisObject.containerName
|
||||
|
||||
let xOffset = label.length / 2 * fontSize * FONT_ASPECT_RATIO
|
||||
let yOffset = (TITLE_BAR_HEIGHT - fontSize) / 2 + 2
|
||||
|
||||
labelPoint = {
|
||||
x: frame.width / 2 - xOffset,
|
||||
x: thisObject.width / 2 - xOffset,
|
||||
y: TITLE_BAR_HEIGHT - yOffset
|
||||
}
|
||||
|
||||
labelPoint = frame.frameThisPoint(labelPoint)
|
||||
labelPoint = thisObject.frameThisPoint(labelPoint)
|
||||
|
||||
if (fitFunction !== undefined) {
|
||||
labelPoint = fitFunction(labelPoint)
|
||||
}
|
||||
|
||||
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', 1)'
|
||||
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y)
|
||||
}
|
||||
|
||||
function borders () {
|
||||
/* Lest get the important points of the drawing so as to apply the needed transformations. */
|
||||
function borders (fitFunction) {
|
||||
/* Lest get the important points of the drawing so as to apply the needed transformations. */
|
||||
|
||||
let point1
|
||||
let point2
|
||||
@@ -408,28 +405,35 @@ function newFrame () {
|
||||
}
|
||||
|
||||
point2 = {
|
||||
x: frame.width,
|
||||
x: thisObject.width,
|
||||
y: 0
|
||||
}
|
||||
|
||||
point3 = {
|
||||
x: frame.width,
|
||||
y: frame.height
|
||||
x: thisObject.width,
|
||||
y: thisObject.height
|
||||
}
|
||||
|
||||
point4 = {
|
||||
x: 0,
|
||||
y: frame.height
|
||||
y: thisObject.height
|
||||
}
|
||||
|
||||
/* Now the transformations. */
|
||||
/* Now the transformations. */
|
||||
|
||||
point1 = transformThisPoint(point1, frame.container)
|
||||
point2 = transformThisPoint(point2, frame.container)
|
||||
point3 = transformThisPoint(point3, frame.container)
|
||||
point4 = transformThisPoint(point4, frame.container)
|
||||
point1 = transformThisPoint(point1, thisObject.container)
|
||||
point2 = transformThisPoint(point2, thisObject.container)
|
||||
point3 = transformThisPoint(point3, thisObject.container)
|
||||
point4 = transformThisPoint(point4, thisObject.container)
|
||||
|
||||
/* Lets start the drawing. */
|
||||
if (fitFunction !== undefined) {
|
||||
point1 = fitFunction(point1)
|
||||
point2 = fitFunction(point2)
|
||||
point3 = fitFunction(point3)
|
||||
point4 = fitFunction(point4)
|
||||
}
|
||||
|
||||
/* Lets start the drawing. */
|
||||
|
||||
browserCanvasContext.beginPath()
|
||||
browserCanvasContext.moveTo(point1.x, point1.y)
|
||||
@@ -446,45 +450,55 @@ function newFrame () {
|
||||
browserCanvasContext.closePath()
|
||||
}
|
||||
|
||||
function grid (smallLines) {
|
||||
function grid (fitFunction, smallLines) {
|
||||
if (smallLines === true) {
|
||||
/* Small Lines */
|
||||
/* Small Lines */
|
||||
|
||||
var step = frame.width / 100
|
||||
let step = thisObject.width / 100
|
||||
|
||||
browserCanvasContext.beginPath()
|
||||
|
||||
for (var i = 0; i < frame.width; i = i + step) {
|
||||
for (var j = 0; j < frame.height; j = j + step) {
|
||||
for (let i = 0; i < thisObject.width; i = i + step) {
|
||||
for (let j = 0; j < thisObject.height; j = j + step) {
|
||||
let point1 = {
|
||||
x: 0,
|
||||
y: j
|
||||
}
|
||||
|
||||
let point2 = {
|
||||
x: frame.width,
|
||||
x: thisObject.width,
|
||||
y: j
|
||||
}
|
||||
|
||||
point1 = transformThisPoint(point1, frame.container)
|
||||
point2 = transformThisPoint(point2, frame.container)
|
||||
point1 = transformThisPoint(point1, thisObject.container)
|
||||
point2 = transformThisPoint(point2, thisObject.container)
|
||||
|
||||
if (fitFunction !== undefined) {
|
||||
point1 = fitFunction(point1)
|
||||
point2 = fitFunction(point2)
|
||||
}
|
||||
|
||||
browserCanvasContext.moveTo(point1.x, point1.y)
|
||||
browserCanvasContext.lineTo(point2.x, point2.y)
|
||||
}
|
||||
|
||||
let point3 = {
|
||||
x: frame.width,
|
||||
y: frame.height
|
||||
x: thisObject.width,
|
||||
y: thisObject.height
|
||||
}
|
||||
|
||||
let point4 = {
|
||||
x: 0,
|
||||
y: frame.height
|
||||
y: thisObject.height
|
||||
}
|
||||
|
||||
point3 = transformThisPoint(point3, frame.container)
|
||||
point4 = transformThisPoint(point4, frame.container)
|
||||
point3 = transformThisPoint(point3, thisObject.container)
|
||||
point4 = transformThisPoint(point4, thisObject.container)
|
||||
|
||||
if (fitFunction !== undefined) {
|
||||
point3 = fitFunction(point3)
|
||||
point4 = fitFunction(point4)
|
||||
}
|
||||
|
||||
browserCanvasContext.moveTo(point3.x, point3.y)
|
||||
browserCanvasContext.lineTo(point4.x, point4.y)
|
||||
@@ -495,26 +509,31 @@ function newFrame () {
|
||||
browserCanvasContext.stroke()
|
||||
}
|
||||
|
||||
/* Main Lines */
|
||||
/* Main Lines */
|
||||
|
||||
var step = frame.width / 20
|
||||
let step = thisObject.width / 20
|
||||
|
||||
browserCanvasContext.beginPath()
|
||||
|
||||
for (var i = 0; i < frame.width; i = i + step) {
|
||||
for (var j = 0; j < frame.height; j = j + step) {
|
||||
for (let i = 0; i < thisObject.width; i = i + step) {
|
||||
for (let j = 0; j < thisObject.height; j = j + step) {
|
||||
let point1 = {
|
||||
x: 0,
|
||||
y: j
|
||||
}
|
||||
|
||||
let point2 = {
|
||||
x: frame.width,
|
||||
x: thisObject.width,
|
||||
y: j
|
||||
}
|
||||
|
||||
point1 = transformThisPoint(point1, frame.container)
|
||||
point2 = transformThisPoint(point2, frame.container)
|
||||
point1 = transformThisPoint(point1, thisObject.container)
|
||||
point2 = transformThisPoint(point2, thisObject.container)
|
||||
|
||||
if (fitFunction !== undefined) {
|
||||
point1 = fitFunction(point1)
|
||||
point2 = fitFunction(point2)
|
||||
}
|
||||
|
||||
browserCanvasContext.moveTo(point1.x, point1.y)
|
||||
browserCanvasContext.lineTo(point2.x, point2.y)
|
||||
@@ -527,11 +546,16 @@ function newFrame () {
|
||||
|
||||
let point4 = {
|
||||
x: i,
|
||||
y: frame.height
|
||||
y: thisObject.height
|
||||
}
|
||||
|
||||
point3 = transformThisPoint(point3, frame.container)
|
||||
point4 = transformThisPoint(point4, frame.container)
|
||||
point3 = transformThisPoint(point3, thisObject.container)
|
||||
point4 = transformThisPoint(point4, thisObject.container)
|
||||
|
||||
if (fitFunction !== undefined) {
|
||||
point3 = fitFunction(point3)
|
||||
point4 = fitFunction(point4)
|
||||
}
|
||||
|
||||
browserCanvasContext.moveTo(point3.x, point3.y)
|
||||
browserCanvasContext.lineTo(point4.x, point4.y)
|
||||
|
||||
+21
-3
@@ -18,14 +18,19 @@ const DEFAULT_MARKET = {
|
||||
UI_COLOR = {
|
||||
DARK: "48, 48, 54",
|
||||
LIGHT: "234, 226, 222",
|
||||
GREY: "150, 150, 150",
|
||||
LIGHT_GREY: "247, 247, 247",
|
||||
WHITE: "255, 255, 255",
|
||||
BLACK: "0, 0, 0",
|
||||
GOLDEN_ORANGE: "240, 162, 2",
|
||||
RUSTED_RED: "204, 88, 53",
|
||||
GREEN: "188, 214, 67",
|
||||
RED: "223, 70, 60",
|
||||
PATINATED_TURQUOISE: "27,153,139",
|
||||
TITANIUM_YELLOW: "244,228,9",
|
||||
MANGANESE_PURPLE: "91,80,122"
|
||||
MANGANESE_PURPLE: "91,80,122",
|
||||
TURQUOISE: "74,207,217",
|
||||
DARK_TURQUOISE: "2,149,170"
|
||||
};
|
||||
|
||||
/* User Interface Fonts */
|
||||
@@ -117,7 +122,17 @@ function convertTimePeriodToName(pTimePeriod) {
|
||||
|
||||
window.AT_BREAKPOINT = false;
|
||||
|
||||
let testUser = window.localStorage.getItem("test_user")
|
||||
let LOGGED_IN_USER_LOCAL_STORAGE_KEY
|
||||
let LOGGED_IN_ACCESS_TOKEN_LOCAL_STORAGE_KEY
|
||||
|
||||
if (testUser !== null) {
|
||||
LOGGED_IN_USER_LOCAL_STORAGE_KEY = "test_user"
|
||||
LOGGED_IN_ACCESS_TOKEN_LOCAL_STORAGE_KEY = "test_access_token"
|
||||
} else {
|
||||
LOGGED_IN_USER_LOCAL_STORAGE_KEY = "user"
|
||||
LOGGED_IN_ACCESS_TOKEN_LOCAL_STORAGE_KEY = "access_token"
|
||||
}
|
||||
|
||||
const USDT_BTC_HTH = 19900; // This is needed to know the scale of the market time line.
|
||||
|
||||
@@ -148,17 +163,20 @@ const _1_MINUTE_IN_MILISECONDS = 1 * 60 * 1000;
|
||||
let NEW_SESSION_INITIAL_DATE = new Date(); // This value will be overwritten at the viewPort.initialize if the user had a prevous session with this same browser.
|
||||
let INITIAL_ZOOM_LEVEL = -28.25 // This is the zoom level at the view port in which the APP starts.
|
||||
let INITIAL_TIME_PERIOD = ONE_DAY_IN_MILISECONDS // This value will be overwritten at the viewPort.initialize if the user had a prevous session with this same browser.
|
||||
let VERY_LARGE_NUMBER = 100000000000
|
||||
|
||||
let maxDate = new Date();
|
||||
maxDate.setMilliseconds(0);
|
||||
maxDate.setDate(maxDate.getDate() + 365 * 1); // We might have charts that projects data into the future.
|
||||
maxDate.setDate(maxDate.getDate() + 365 * 1); // We might have charts that projects data into the future.
|
||||
|
||||
const MIN_PLOTABLE_DATE = new Date(2015, 0, 1, 0, 0, 0);
|
||||
const MAX_PLOTABLE_DATE = maxDate;
|
||||
|
||||
const TOP_SPACE_HEIGHT = 5;
|
||||
const BOTTOM_SPACE_HEIGHT = 35;
|
||||
const COCKPIT_SPACE_HEIGHT = 40;
|
||||
const BREAKPOINT_HEIGHT = 15;
|
||||
const SIDE_PANEL_WIDTH = 450
|
||||
let COCKPIT_SPACE_POSITION = browserCanvas.height - COCKPIT_SPACE_HEIGHT
|
||||
|
||||
const PRODUCT_CARD_STATUS = {
|
||||
ON: 'on',
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
function newPanelTabButton () {
|
||||
let thisObject = {
|
||||
container: undefined,
|
||||
draw: draw,
|
||||
fitFunction: undefined,
|
||||
parentContainer: undefined,
|
||||
draw: draw,
|
||||
getContainer: getContainer, // returns the inner most container that holds the point received by parameter.
|
||||
initialize: initialize
|
||||
}
|
||||
@@ -203,6 +204,12 @@ function newPanelTabButton () {
|
||||
point2 = thisObject.container.frame.frameThisPoint(point2)
|
||||
point3 = thisObject.container.frame.frameThisPoint(point3)
|
||||
|
||||
if (thisObject.fitFunction !== undefined) {
|
||||
point1 = thisObject.fitFunction(point1)
|
||||
point2 = thisObject.fitFunction(point2)
|
||||
point3 = thisObject.fitFunction(point3)
|
||||
}
|
||||
|
||||
/* Lets start the drawing. */
|
||||
|
||||
browserCanvasContext.beginPath()
|
||||
@@ -220,4 +227,3 @@ function newPanelTabButton () {
|
||||
browserCanvasContext.fill()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,15 +16,13 @@ function newProductCard () {
|
||||
bot: undefined,
|
||||
product: undefined,
|
||||
code: undefined,
|
||||
|
||||
fitFunction: undefined,
|
||||
setDatetime: setDatetime,
|
||||
setTimePeriod: setTimePeriod,
|
||||
|
||||
onMarketFileLoaded: onMarketFileLoaded,
|
||||
onDailyFileLoaded: onDailyFileLoaded,
|
||||
onSingleFileLoaded: onSingleFileLoaded,
|
||||
onFileSequenceLoaded: onFileSequenceLoaded,
|
||||
|
||||
getContainer: getContainer, // returns the inner most container that holds the point received by parameter.
|
||||
initialize: initialize
|
||||
}
|
||||
@@ -429,6 +427,11 @@ function newProductCard () {
|
||||
|
||||
*/
|
||||
|
||||
let fitImagePoint = {
|
||||
x: 0,
|
||||
y: 0
|
||||
}
|
||||
|
||||
const devTeamImageSize = 20
|
||||
const botImageSize = 20
|
||||
const plotterImageSize = {
|
||||
@@ -448,6 +451,8 @@ function newProductCard () {
|
||||
|
||||
teamImagePoint = thisObject.container.frame.frameThisPoint(teamImagePoint)
|
||||
|
||||
fitImagePoint = thisObject.fitFunction(teamImagePoint)
|
||||
|
||||
let teamImage
|
||||
|
||||
if (legacyTeamAvatarLoaded === true) {
|
||||
@@ -458,7 +463,7 @@ function newProductCard () {
|
||||
teamImage = teamAvatar
|
||||
}
|
||||
|
||||
if (teamImage !== undefined) {
|
||||
if (teamImage !== undefined && teamImagePoint.y === fitImagePoint.y) {
|
||||
if (teamImage.naturalHeight !== 0) {
|
||||
/* The image is rounded before being displayed. */
|
||||
|
||||
@@ -485,6 +490,7 @@ function newProductCard () {
|
||||
}
|
||||
|
||||
botImagePoint = thisObject.container.frame.frameThisPoint(botImagePoint)
|
||||
fitImagePoint = thisObject.fitFunction(botImagePoint)
|
||||
|
||||
let imageId = thisObject.bot.devTeam + '.' + thisObject.bot.profilePicture
|
||||
|
||||
@@ -493,7 +499,7 @@ function newProductCard () {
|
||||
|
||||
botImage = thisObject.bot.avatar
|
||||
|
||||
if (botImage !== undefined) {
|
||||
if (botImage !== undefined && botImagePoint.y === fitImagePoint.y) {
|
||||
if (botImage.naturalHeight !== 0) {
|
||||
/* The image is rounded before being displayed. */
|
||||
|
||||
@@ -522,11 +528,17 @@ function newProductCard () {
|
||||
}
|
||||
|
||||
plotterImagePoint = thisObject.container.frame.frameThisPoint(plotterImagePoint)
|
||||
fitImagePoint = {
|
||||
x: 0,
|
||||
y: plotterImagePoint.y + plotterImageSize.height
|
||||
}
|
||||
|
||||
fitImagePoint = thisObject.fitFunction(fitImagePoint)
|
||||
|
||||
let imageId = thisObject.product.plotter.devTeam + '.' + thisObject.product.plotter.codeName + '.' + thisObject.product.plotter.moduleName + '.' + thisObject.product.plotter.profilePicture
|
||||
let plotterImage = legacyPlotterBanner
|
||||
|
||||
if (plotterImage !== undefined) {
|
||||
if (plotterImage !== undefined && plotterImagePoint.y + plotterImageSize.height === fitImagePoint.y) {
|
||||
if (plotterImage.naturalHeight !== 0) {
|
||||
browserCanvasContext.drawImage(plotterImage, plotterImagePoint.x, plotterImagePoint.y, plotterImageSize.width, plotterImageSize.height)
|
||||
}
|
||||
@@ -588,6 +600,11 @@ function newProductCard () {
|
||||
point3 = thisObject.container.frame.frameThisPoint(point3)
|
||||
point4 = thisObject.container.frame.frameThisPoint(point4)
|
||||
|
||||
point1 = thisObject.fitFunction(point1)
|
||||
point2 = thisObject.fitFunction(point2)
|
||||
point3 = thisObject.fitFunction(point3)
|
||||
point4 = thisObject.fitFunction(point4)
|
||||
|
||||
browserCanvasContext.beginPath()
|
||||
browserCanvasContext.moveTo(point1.x, point1.y)
|
||||
browserCanvasContext.lineTo(point2.x, point2.y)
|
||||
@@ -609,7 +626,7 @@ function newProductCard () {
|
||||
let labelPoint
|
||||
let fontSize = 10
|
||||
|
||||
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.SECONDARY + ' Saira'
|
||||
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
|
||||
|
||||
let label
|
||||
|
||||
@@ -625,8 +642,9 @@ function newProductCard () {
|
||||
}
|
||||
|
||||
labelPoint = thisObject.container.frame.frameThisPoint(labelPoint)
|
||||
labelPoint = thisObject.fitFunction(labelPoint)
|
||||
|
||||
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.SECONDARY + ' Saira'
|
||||
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
|
||||
browserCanvasContext.fillStyle = 'rgba(60, 60, 60, 0.50)'
|
||||
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y)
|
||||
|
||||
@@ -641,8 +659,9 @@ function newProductCard () {
|
||||
}
|
||||
|
||||
labelPoint = thisObject.container.frame.frameThisPoint(labelPoint)
|
||||
labelPoint = thisObject.fitFunction(labelPoint)
|
||||
|
||||
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.SECONDARY + ' Saira'
|
||||
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
|
||||
browserCanvasContext.fillStyle = 'rgba(60, 60, 60, 0.50)'
|
||||
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y)
|
||||
}
|
||||
@@ -664,8 +683,9 @@ function newProductCard () {
|
||||
}
|
||||
|
||||
labelPoint = thisObject.container.frame.frameThisPoint(labelPoint)
|
||||
labelPoint = thisObject.fitFunction(labelPoint)
|
||||
|
||||
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.SECONDARY + ' Saira'
|
||||
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
|
||||
browserCanvasContext.fillStyle = 'rgba(60, 60, 60, 0.50)'
|
||||
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y)
|
||||
|
||||
@@ -728,6 +748,11 @@ function newProductCard () {
|
||||
point3 = thisObject.container.frame.frameThisPoint(point3)
|
||||
point4 = thisObject.container.frame.frameThisPoint(point4)
|
||||
|
||||
point1 = thisObject.fitFunction(point1)
|
||||
point2 = thisObject.fitFunction(point2)
|
||||
point3 = thisObject.fitFunction(point3)
|
||||
point4 = thisObject.fitFunction(point4)
|
||||
|
||||
browserCanvasContext.beginPath()
|
||||
browserCanvasContext.moveTo(point1.x, point1.y)
|
||||
browserCanvasContext.lineTo(point2.x, point2.y)
|
||||
@@ -790,6 +815,11 @@ function newProductCard () {
|
||||
point3 = thisObject.container.frame.frameThisPoint(point3)
|
||||
point4 = thisObject.container.frame.frameThisPoint(point4)
|
||||
|
||||
point1 = thisObject.fitFunction(point1)
|
||||
point2 = thisObject.fitFunction(point2)
|
||||
point3 = thisObject.fitFunction(point3)
|
||||
point4 = thisObject.fitFunction(point4)
|
||||
|
||||
browserCanvasContext.beginPath()
|
||||
browserCanvasContext.moveTo(point1.x, point1.y)
|
||||
browserCanvasContext.lineTo(point2.x, point2.y)
|
||||
@@ -852,6 +882,11 @@ function newProductCard () {
|
||||
point3 = thisObject.container.frame.frameThisPoint(point3)
|
||||
point4 = thisObject.container.frame.frameThisPoint(point4)
|
||||
|
||||
point1 = thisObject.fitFunction(point1)
|
||||
point2 = thisObject.fitFunction(point2)
|
||||
point3 = thisObject.fitFunction(point3)
|
||||
point4 = thisObject.fitFunction(point4)
|
||||
|
||||
browserCanvasContext.beginPath()
|
||||
browserCanvasContext.moveTo(point1.x, point1.y)
|
||||
browserCanvasContext.lineTo(point2.x, point2.y)
|
||||
@@ -914,6 +949,11 @@ function newProductCard () {
|
||||
point3 = thisObject.container.frame.frameThisPoint(point3)
|
||||
point4 = thisObject.container.frame.frameThisPoint(point4)
|
||||
|
||||
point1 = thisObject.fitFunction(point1)
|
||||
point2 = thisObject.fitFunction(point2)
|
||||
point3 = thisObject.fitFunction(point3)
|
||||
point4 = thisObject.fitFunction(point4)
|
||||
|
||||
browserCanvasContext.beginPath()
|
||||
browserCanvasContext.moveTo(point1.x, point1.y)
|
||||
browserCanvasContext.lineTo(point2.x, point2.y)
|
||||
@@ -929,4 +969,3 @@ function newProductCard () {
|
||||
browserCanvasContext.stroke()
|
||||
}
|
||||
}
|
||||
|
||||
+196
-170
@@ -1,242 +1,268 @@
|
||||
function newProductsPanel () {
|
||||
let thisObject = {
|
||||
container: undefined,
|
||||
getLoadingProductCards: getLoadingProductCards,
|
||||
draw: draw,
|
||||
getContainer: getContainer, // returns the inner most container that holds the point received by parameter.
|
||||
initialize: initialize
|
||||
}
|
||||
function newProductsPanel () {
|
||||
let thisObject = {
|
||||
fitFunction: undefined,
|
||||
container: undefined,
|
||||
getLoadingProductCards: getLoadingProductCards,
|
||||
draw: draw,
|
||||
getContainer: getContainer, // returns the inner most container that holds the point received by parameter.
|
||||
initialize: initialize
|
||||
}
|
||||
|
||||
/* Cointainer stuff */
|
||||
/* Cointainer stuff */
|
||||
|
||||
var container = newContainer()
|
||||
let container = newContainer()
|
||||
|
||||
container.initialize()
|
||||
container.initialize()
|
||||
|
||||
container.isDraggeable = true
|
||||
container.isWheelable = true
|
||||
container.isDraggeable = true
|
||||
container.isWheelable = true
|
||||
|
||||
thisObject.container = container
|
||||
thisObject.container = container
|
||||
|
||||
let isInitialized = false
|
||||
let productCards = []
|
||||
let isInitialized = false
|
||||
let productCards = []
|
||||
|
||||
let visibleProductCards = []
|
||||
let firstVisibleCard = 1
|
||||
let visibleProductCards = []
|
||||
let firstVisibleCard = 1
|
||||
|
||||
/* Needed Variables */
|
||||
/* Needed Variables */
|
||||
|
||||
let lastY = 5
|
||||
let panelTabButton
|
||||
let lastY = 5
|
||||
let panelTabButton
|
||||
|
||||
let exchange
|
||||
let market
|
||||
let exchange
|
||||
let market
|
||||
|
||||
return thisObject
|
||||
return thisObject
|
||||
|
||||
function initialize (pExchange, pMarket) {
|
||||
exchange = pExchange
|
||||
market = pMarket
|
||||
function initialize (pExchange, pMarket) {
|
||||
exchange = pExchange
|
||||
market = pMarket
|
||||
|
||||
thisObject.container.name = 'Layers @ ' + exchange + ' ' + market.assetB + '/' + market.assetA
|
||||
thisObject.container.frame.containerName = thisObject.container.name
|
||||
thisObject.container.frame.width = UI_PANEL.WIDTH.LARGE
|
||||
thisObject.container.frame.height = viewPort.visibleArea.bottomLeft.y - viewPort.visibleArea.topLeft.y // UI_PANEL.HEIGHT.LARGE;
|
||||
thisObject.container.name = 'Layers @ ' + exchange + ' ' + market.assetB + '/' + market.assetA
|
||||
thisObject.container.frame.containerName = thisObject.container.name
|
||||
thisObject.container.frame.width = UI_PANEL.WIDTH.LARGE
|
||||
thisObject.container.frame.height = UI_PANEL.HEIGHT.LARGE // viewPort.visibleArea.bottomLeft.y - viewPort.visibleArea.topLeft.y // UI_PANEL.HEIGHT.LARGE;
|
||||
|
||||
var position = {
|
||||
x: viewPort.visibleArea.topLeft.x,
|
||||
y: viewPort.visibleArea.bottomLeft.y - thisObject.container.frame.height
|
||||
}
|
||||
let position = {
|
||||
x: viewPort.visibleArea.topLeft.x,
|
||||
y: viewPort.visibleArea.topLeft.y// viewPort.visibleArea.bottomLeft.y - thisObject.container.frame.height
|
||||
}
|
||||
|
||||
thisObject.container.frame.position = position
|
||||
thisObject.container.frame.position = position
|
||||
|
||||
panelTabButton = newPanelTabButton()
|
||||
panelTabButton.parentContainer = thisObject.container
|
||||
panelTabButton.container.frame.parentFrame = thisObject.container.frame
|
||||
panelTabButton.initialize()
|
||||
panelTabButton = newPanelTabButton()
|
||||
panelTabButton.parentContainer = thisObject.container
|
||||
panelTabButton.container.frame.parentFrame = thisObject.container.frame
|
||||
panelTabButton.fitFunction = thisObject.fitFunction
|
||||
panelTabButton.initialize()
|
||||
|
||||
/* Get the current teams of the logged in user. */
|
||||
/* Get the current teams of the logged in user. */
|
||||
|
||||
let storedTeams = window.localStorage.getItem('userTeams')
|
||||
let userTeams
|
||||
let userTeam = {slug: ''}
|
||||
if (storedTeams !== null && storedTeams !== undefined && storedTeams !== '') {
|
||||
userTeams = JSON.parse(storedTeams)
|
||||
userTeam = userTeams[0] // Currently we assume a user can be at only one team.
|
||||
}
|
||||
if (userTeam === undefined) { userTeam = {slug: ''} }
|
||||
let storedTeams = window.localStorage.getItem('userTeams')
|
||||
let userTeams
|
||||
if (storedTeams !== null && storedTeams !== undefined && storedTeams !== '') {
|
||||
userTeams = JSON.parse(storedTeams)
|
||||
}
|
||||
|
||||
/* First thing is to build the productCards array */
|
||||
/* First thing is to build the productCards array */
|
||||
|
||||
let devTeams = ecosystem.getTeams()
|
||||
let devTeams = ecosystem.getTeams()
|
||||
|
||||
for (let i = 0; i < devTeams.length; i++) {
|
||||
let devTeam = devTeams[i]
|
||||
for (let i = 0; i < devTeams.length; i++) {
|
||||
let devTeam = devTeams[i]
|
||||
|
||||
for (let j = 0; j < devTeam.bots.length; j++) {
|
||||
let bot = devTeam.bots[j]
|
||||
for (let j = 0; j < devTeam.bots.length; j++) {
|
||||
let bot = devTeam.bots[j]
|
||||
let userTeam = isUserTeam(devTeam.codeName, userTeams)
|
||||
if (bot.type !== 'Indicator' && bot.cloneId === undefined) { continue }
|
||||
|
||||
if (bot.type !== 'Indicator' && bot.cloneId === undefined) { continue }
|
||||
if (bot.type === 'Indicator' && (devTeam.codeName !== 'AAMasters' && devTeam.codeName !== userTeam.slug)) { continue }
|
||||
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]
|
||||
if (product.shareWith !== 'Public' && devTeam.codeName !== userTeam.slug) { continue }
|
||||
/* Now we create Product objects */
|
||||
if (window.localStorage.getItem('Show AAMaster Layers') === null) {
|
||||
if (product.shareWith !== 'Public' && !userTeam) { continue }
|
||||
}
|
||||
/* Now we create Product objects */
|
||||
|
||||
let productCard = newProductCard()
|
||||
let productCard = newProductCard()
|
||||
|
||||
productCard.devTeam = devTeam
|
||||
productCard.bot = bot
|
||||
productCard.product = product
|
||||
productCard.devTeam = devTeam
|
||||
productCard.bot = bot
|
||||
productCard.product = product
|
||||
productCard.fitFunction = thisObject.fitFunction
|
||||
productCard.code = exchange + '-' + market.assetB + '/' + market.assetA + '-' + devTeam.codeName + '-' + bot.codeName + '-' + product.codeName
|
||||
|
||||
productCard.code = exchange + '-' + market.assetB + '/' + market.assetA + '-' + devTeam.codeName + '-' + bot.codeName + '-' + product.codeName
|
||||
/* Initialize it */
|
||||
|
||||
/* Initialize it */
|
||||
productCard.initialize()
|
||||
|
||||
productCard.initialize()
|
||||
/* Container Stuff */
|
||||
|
||||
/* Container Stuff */
|
||||
productCard.container.displacement.parentDisplacement = thisObject.container.displacement
|
||||
productCard.container.frame.parentFrame = thisObject.container.frame
|
||||
productCard.container.parentContainer = thisObject.container
|
||||
productCard.container.isWheelable = true
|
||||
|
||||
productCard.container.displacement.parentDisplacement = thisObject.container.displacement
|
||||
productCard.container.frame.parentFrame = thisObject.container.frame
|
||||
productCard.container.parentContainer = thisObject.container
|
||||
productCard.container.isWheelable = true
|
||||
/* Positioning within thisObject Panel */
|
||||
|
||||
/* Positioning within thisObject Panel */
|
||||
let position = {
|
||||
x: 10,
|
||||
y: thisObject.container.frame.height - thisObject.container.frame.getBodyHeight()
|
||||
}
|
||||
|
||||
let position = {
|
||||
x: 10,
|
||||
y: thisObject.container.frame.height - thisObject.container.frame.getBodyHeight()
|
||||
}
|
||||
productCard.container.frame.position.x = position.x
|
||||
productCard.container.frame.position.y = position.y + lastY
|
||||
|
||||
productCard.container.frame.position.x = position.x
|
||||
productCard.container.frame.position.y = position.y + lastY
|
||||
lastY = lastY + productCard.container.frame.height
|
||||
|
||||
lastY = lastY + productCard.container.frame.height
|
||||
/* Add to the Product Array */
|
||||
|
||||
/* Add to the Product Array */
|
||||
productCards.push(productCard)
|
||||
|
||||
productCards.push(productCard)
|
||||
/* Add to Visible Product Array */
|
||||
|
||||
/* Add to Visible Product Array */
|
||||
if (productCard.container.frame.position.y + productCard.container.frame.height < thisObject.container.frame.height) {
|
||||
visibleProductCards.push(productCard)
|
||||
}
|
||||
|
||||
if (productCard.container.frame.position.y + productCard.container.frame.height < thisObject.container.frame.height) {
|
||||
visibleProductCards.push(productCard)
|
||||
}
|
||||
/* Listen to Status Changes Events */
|
||||
|
||||
/* Listen to Status Changes Events */
|
||||
productCard.container.eventHandler.listenToEvent('Status Changed', onProductCardStatusChanged)
|
||||
productCard.container.eventHandler.listenToEvent('onMouseWheel', onMouseWheel)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
productCard.container.eventHandler.listenToEvent('Status Changed', onProductCardStatusChanged)
|
||||
productCard.container.eventHandler.listenToEvent('Mouse Wheel', onMouseWheel)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
thisObject.container.eventHandler.listenToEvent('onMouseWheel', onMouseWheel)
|
||||
isInitialized = true
|
||||
}
|
||||
|
||||
thisObject.container.eventHandler.listenToEvent('Mouse Wheel', onMouseWheel)
|
||||
isInitialized = true
|
||||
}
|
||||
function onMouseWheel (event) {
|
||||
delta = event.wheelDelta
|
||||
if (delta > 0) {
|
||||
delta = -1
|
||||
} else {
|
||||
delta = 1
|
||||
}
|
||||
|
||||
function onMouseWheel (event) {
|
||||
delta = event.wheelDelta
|
||||
if (delta > 0) {
|
||||
delta = -1
|
||||
} else {
|
||||
delta = 1
|
||||
}
|
||||
firstVisibleCard = firstVisibleCard + delta
|
||||
|
||||
firstVisibleCard = firstVisibleCard + delta
|
||||
let availableSlots = visibleProductCards.length
|
||||
|
||||
let availableSlots = visibleProductCards.length
|
||||
if (firstVisibleCard < 1) { firstVisibleCard = 1 }
|
||||
if (firstVisibleCard > (productCards.length - availableSlots + 1)) { firstVisibleCard = productCards.length - availableSlots + 1 }
|
||||
|
||||
if (firstVisibleCard < 1) { firstVisibleCard = 1 }
|
||||
if (firstVisibleCard > (productCards.length - availableSlots + 1)) { firstVisibleCard = productCards.length - availableSlots + 1 }
|
||||
visibleProductCards = []
|
||||
let lastY = 5
|
||||
|
||||
visibleProductCards = []
|
||||
var lastY = 5
|
||||
for (let i = 0; i < productCards.length; i++) {
|
||||
if (i + 1 >= firstVisibleCard && i + 1 < firstVisibleCard + availableSlots) {
|
||||
let productCard = productCards[i]
|
||||
|
||||
for (let i = 0; i < productCards.length; i++) {
|
||||
if (i + 1 >= firstVisibleCard && i + 1 < firstVisibleCard + availableSlots) {
|
||||
let productCard = productCards[i]
|
||||
/* Positioning within thisObject Panel */
|
||||
|
||||
/* Positioning within thisObject Panel */
|
||||
let position = {
|
||||
x: 10,
|
||||
y: thisObject.container.frame.height - thisObject.container.frame.getBodyHeight()
|
||||
}
|
||||
productCard.container.frame.position.x = position.x
|
||||
productCard.container.frame.position.y = position.y + lastY
|
||||
|
||||
let position = {
|
||||
x: 10,
|
||||
y: thisObject.container.frame.height - thisObject.container.frame.getBodyHeight()
|
||||
}
|
||||
productCard.container.frame.position.x = position.x
|
||||
productCard.container.frame.position.y = position.y + lastY
|
||||
lastY = lastY + productCard.container.frame.height
|
||||
|
||||
lastY = lastY + productCard.container.frame.height
|
||||
/* Add to Visible Product Array */
|
||||
|
||||
/* Add to Visible Product Array */
|
||||
visibleProductCards.push(productCard)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
visibleProductCards.push(productCard)
|
||||
}
|
||||
}
|
||||
}
|
||||
function onProductCardStatusChanged (pProductCard) {
|
||||
thisObject.container.eventHandler.raiseEvent('Product Card Status Changed', pProductCard)
|
||||
}
|
||||
|
||||
function onProductCardStatusChanged (pProductCard) {
|
||||
thisObject.container.eventHandler.raiseEvent('Product Card Status Changed', pProductCard)
|
||||
}
|
||||
function getLoadingProductCards () {
|
||||
/* Returns all productCards which status is LOADING */
|
||||
|
||||
function getLoadingProductCards () {
|
||||
/* Returns all productCards which status is LOADING */
|
||||
let onProducts = []
|
||||
|
||||
let onProducts = []
|
||||
for (let i = 0; i < productCards.length; i++) {
|
||||
if (productCards[i].status === PRODUCT_CARD_STATUS.LOADING) {
|
||||
onProducts.push(productCards[i])
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < productCards.length; i++) {
|
||||
if (productCards[i].status === PRODUCT_CARD_STATUS.LOADING) {
|
||||
onProducts.push(productCards[i])
|
||||
}
|
||||
}
|
||||
return onProducts
|
||||
}
|
||||
|
||||
return onProducts
|
||||
}
|
||||
function getContainer (point) {
|
||||
let container
|
||||
|
||||
function getContainer (point) {
|
||||
var container
|
||||
container = panelTabButton.getContainer(point)
|
||||
if (container !== undefined) { return container }
|
||||
|
||||
container = panelTabButton.getContainer(point)
|
||||
if (container !== undefined) { return container }
|
||||
/* First we check if thisObject point is inside thisObject space. */
|
||||
|
||||
/* First we check if thisObject point is inside thisObject space. */
|
||||
if (thisObject.container.frame.isThisPointHere(point, true) === true) {
|
||||
/* Now we see which is the inner most container that has it */
|
||||
|
||||
if (thisObject.container.frame.isThisPointHere(point, true) === true) {
|
||||
/* Now we see which is the inner most container that has it */
|
||||
for (let i = 0; i < visibleProductCards.length; i++) {
|
||||
container = visibleProductCards[i].getContainer(point)
|
||||
|
||||
for (var i = 0; i < visibleProductCards.length; i++) {
|
||||
container = visibleProductCards[i].getContainer(point)
|
||||
if (container !== undefined) {
|
||||
let checkPoint = {
|
||||
x: point.x,
|
||||
y: point.y
|
||||
}
|
||||
|
||||
if (container !== undefined) {
|
||||
/* We found an inner container which has the point. We return it. */
|
||||
checkPoint = thisObject.fitFunction(checkPoint)
|
||||
|
||||
return container
|
||||
}
|
||||
}
|
||||
if (point.x === checkPoint.x && point.y === checkPoint.y) {
|
||||
return container
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* The point does not belong to any inner container, so we return the current container. */
|
||||
/* The point does not belong to any inner container, so we return the current container. */
|
||||
|
||||
return thisObject.container
|
||||
} else {
|
||||
/* This point does not belong to thisObject space. */
|
||||
let checkPoint = {
|
||||
x: point.x,
|
||||
y: point.y
|
||||
}
|
||||
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
checkPoint = thisObject.fitFunction(checkPoint)
|
||||
|
||||
function draw () {
|
||||
if (isInitialized === false) { return }
|
||||
if (point.x === checkPoint.x && point.y === checkPoint.y) {
|
||||
return thisObject.container
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
thisObject.container.frame.draw(false, false, true)
|
||||
function draw () {
|
||||
if (isInitialized === false) { return }
|
||||
|
||||
for (let i = 0; i < visibleProductCards.length; i++) {
|
||||
visibleProductCards[i].draw()
|
||||
}
|
||||
thisObject.container.frame.draw(false, false, true, thisObject.fitFunction)
|
||||
|
||||
for (let i = 0; i < visibleProductCards.length; i++) {
|
||||
visibleProductCards[i].draw()
|
||||
}
|
||||
|
||||
panelTabButton.draw()
|
||||
}
|
||||
|
||||
function isUserTeam(team, userTeams){
|
||||
if(userTeams === undefined)
|
||||
return false
|
||||
|
||||
for (let index = 0; index < userTeams.length; index++) {
|
||||
if(team === userTeams[index].slug){
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
panelTabButton.draw()
|
||||
}
|
||||
}
|
||||
@@ -115,7 +115,7 @@ function newTimeControlPanel () {
|
||||
|
||||
labelPoint = thisObject.container.frame.frameThisPoint(labelPoint)
|
||||
|
||||
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.SECONDARY + ' Saira'
|
||||
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
|
||||
browserCanvasContext.fillStyle = 'rgba(60, 60, 60, 0.50)'
|
||||
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y)
|
||||
|
||||
@@ -132,7 +132,7 @@ function newTimeControlPanel () {
|
||||
|
||||
labelPoint = thisObject.container.frame.frameThisPoint(labelPoint)
|
||||
|
||||
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.SECONDARY + ' Saira'
|
||||
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
|
||||
browserCanvasContext.fillStyle = 'rgba(60, 60, 60, 0.50)'
|
||||
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y)
|
||||
|
||||
@@ -151,7 +151,7 @@ function newTimeControlPanel () {
|
||||
|
||||
labelPoint = thisObject.container.frame.frameThisPoint(labelPoint)
|
||||
|
||||
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.SECONDARY + ' Saira'
|
||||
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
|
||||
browserCanvasContext.fillStyle = 'rgba(60, 60, 60, 0.50)'
|
||||
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y)
|
||||
}
|
||||
|
||||
+4
-4
@@ -171,7 +171,7 @@ function newProductStorage (pName) {
|
||||
|
||||
case GLOBAL.CUSTOM_FAIL_RESPONSE.result: {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] initialize -> onMarketFileReady -> Received CUSTOM FAIL Response.') }
|
||||
if (INFO_LOG === true) { logger.write('[INFO] initialize -> onMarketFileReady -> err.message = ' + err.message) }
|
||||
if (INFO_LOG === true) { logger.write('[INFO] initialize -> onMarketFileReady -> err= ' + err.stack) }
|
||||
|
||||
callBackFunction(err)
|
||||
return
|
||||
@@ -227,7 +227,7 @@ function newProductStorage (pName) {
|
||||
|
||||
case GLOBAL.CUSTOM_FAIL_RESPONSE.result: {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] initialize -> onDailyFileReady -> Received CUSTOM FAIL Response.') }
|
||||
if (INFO_LOG === true) { logger.write('[INFO] initialize -> onDailyFileReady -> err.message = ' + err.message) }
|
||||
if (INFO_LOG === true) { logger.write('[INFO] initialize -> onDailyFileReady -> err= ' + err.stack) }
|
||||
|
||||
callBackFunction(err)
|
||||
return
|
||||
@@ -282,7 +282,7 @@ function newProductStorage (pName) {
|
||||
|
||||
case GLOBAL.CUSTOM_FAIL_RESPONSE.result: {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] initialize -> onSingleFileReady -> Received CUSTOM FAIL Response.') }
|
||||
if (INFO_LOG === true) { logger.write('[INFO] initialize -> onSingleFileReady -> err.message = ' + err.message) }
|
||||
if (INFO_LOG === true) { logger.write('[INFO] initialize -> onSingleFileReady -> err= ' + err.stack) }
|
||||
|
||||
callBackFunction(err)
|
||||
return
|
||||
@@ -334,7 +334,7 @@ function newProductStorage (pName) {
|
||||
|
||||
case GLOBAL.CUSTOM_FAIL_RESPONSE.result: {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] initialize -> onFileSequenceReady -> Received CUSTOM FAIL Response.') }
|
||||
if (INFO_LOG === true) { logger.write('[INFO] initialize -> onFileSequenceReady -> err.message = ' + err.message) }
|
||||
if (INFO_LOG === true) { logger.write('[INFO] initialize -> onFileSequenceReady -> err= ' + err.stack) }
|
||||
|
||||
callBackFunction(err)
|
||||
return
|
||||
|
||||
+5
-5
@@ -32,13 +32,13 @@
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Animation.js" />
|
||||
<Compile Include="BottomSpace\DeleteTradingHistory.js">
|
||||
<Compile Include="CockpitSpace\DeleteTradingHistory.js">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="BreakpointsBar.js">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="BottomSpace\ChartAspectRatio.js">
|
||||
<Compile Include="CockpitSpace\ChartAspectRatio.js">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="CloudVM\CloudRequire.js">
|
||||
@@ -85,7 +85,7 @@
|
||||
<Compile Include="ImageButton.js">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Spaces\BottomSpace.js">
|
||||
<Compile Include="Spaces\CockpitSpace.js">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Spaces\TopSpace.js">
|
||||
@@ -112,7 +112,7 @@
|
||||
<Compile Include="TopSpace\EndUser.js">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="BottomSpace\PlayStopButton.js">
|
||||
<Compile Include="CockpitSpace\PlayStopButton.js">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="WebDebugLog.js">
|
||||
@@ -177,7 +177,7 @@
|
||||
<Folder Include="Exchange\" />
|
||||
<Folder Include="Files\" />
|
||||
<Folder Include="FloatingSpace\" />
|
||||
<Folder Include="BottomSpace\" />
|
||||
<Folder Include="CockpitSpace\" />
|
||||
<Folder Include="Scales\" />
|
||||
<Folder Include="TopSpace\" />
|
||||
<Folder Include="Spaces\" />
|
||||
|
||||
@@ -1,15 +1,115 @@
|
||||
# Welcome to the Canvas App
|
||||
|
||||
The Canvas App is the in-house charting system of Superalgos. It is the software capable of running the Plotters that can represent datasets graphically.
|
||||
The Canvas App is the built-in charting system of Superalgos. It is the software capable of running the Plotters that represent datasets graphically.
|
||||
|
||||

|
||||

|
||||
|
||||
## Installation
|
||||
|
||||
To install the Canvas App, you need to install AAWeb. Please follow this guide:
|
||||
To install the Canvas App, you need to install AAWeb, following this guide:
|
||||
|
||||
https://github.com/Superalgos/AAWeb/blob/develop/README.md
|
||||
|
||||
## Usage
|
||||
|
||||
Use your mouse wheel to zoom out and zoom in, and left click to drag and drop the charts. The Canvas App is designed to have a similar experience than Google Maps in the sense that allows you to easily navigate through different markets, potentially at different exchanges just by zooming out, dragging / dropping and zooming in at your destination.
|
||||
The first time you access the Canvas App, you will see the following screen with no chart displayed, since the app expects you to select one of the available layers at the Layers Panel on the left:
|
||||
|
||||

|
||||
|
||||
### Layers Panel
|
||||
|
||||
This panel includes different layers you may visualize by toggling them on and off with a single mouse clicks.
|
||||
The layer title bar can have 3 possible background colors:
|
||||
|
||||
1. **Red**: layer is off.
|
||||
2. **Green**: layer is on.
|
||||
3. **Yellow**: layer is loading. If it stays yellow, it means it can't load fully.
|
||||
|
||||
Click on the "Candles" layer and wait a few seconds date is loaded and candles are plotted. You should see something like this:
|
||||
|
||||

|
||||
|
||||
As you may see, the candles belong to the BTC/USDT market @ Poloniex. Even though the app supports other markets and exchanges, it is better for us to have only this one active, while the codebase matures.
|
||||
|
||||
Notice the following 3 elements relative to the position of the mouse pointer:
|
||||
|
||||
### Main Elements
|
||||
|
||||
1. Above, the current datetime. This is the date and time at the mouse pointer position.
|
||||
2. To the right, the current rate. This is the rate (in this case USDT per BTC) at the mouse pointer position.
|
||||
3. Below, the current time period (or candle size if you wish). This is the currently displayed time period—not only for candles, but for any other object plotted across available layers.
|
||||
|
||||
### Mouse Wheel Operations
|
||||
|
||||
There are many things you can do with your mouse wheel.
|
||||
|
||||
1. Scroll on top of or next to the datetime to produce a horizontal scaling.
|
||||
1. Scroll on top of or next to the displayed rate to produce a vertical scaling.
|
||||
1. Scroll on top of or next to the time period to change the time period to available values.
|
||||
1. Scroll elsewhere over the chart to zoom in and out. The App will not only zoom in and out of the chart, but also automatically adjust the time period to the most convenient one (for the current zoom level).
|
||||
1. Scroll over the Layers Panel to access layers that may be out of reach downwards.
|
||||
|
||||
After zooming in the main elements stay at the top, left and bottom of the viewport as you can see in the next screenshot:
|
||||
|
||||

|
||||
|
||||
### Moving Panels
|
||||
|
||||
Drag and drop right-clicking on the title bar.
|
||||
|
||||
### Minimizing Panels
|
||||
|
||||
Click on the small triangle on the right of their title bar. This will automatically position the panel at the bottom of the screen. Clicking again restores the panel to its previous position.
|
||||
|
||||
In the following image, the Layers Panel was dragged to the left and the Current Candle Panel was minimized:
|
||||
|
||||

|
||||
|
||||
### Layers
|
||||
|
||||
Superalgos is an open system, meaning anyone can build layers for this charting app. So far—with our current limited manpower—we have created 8 public layers (available without logging in) and 2 private layers (available to logged-in users):
|
||||
|
||||
#### Public Layers
|
||||
|
||||
1. **Candles**: Typical candlesticks.
|
||||
|
||||

|
||||
|
||||
2. **Volumes**: I innovated a bit placing the buy volume at the bottom (in green), and the sell volume at the top (in red).
|
||||
|
||||

|
||||
|
||||
3. **Candle Stairs Patterns**: This is an unusual pattern proving any dataset may be plotted on the charts (and by extension, that anything can be added to the system). A Stair Pattern is defined as a set of candles going in the same direction, either up or down. You can think of these patterns as "Candle Channels", as they represent channels with an up or down direction based on underlying candles direction.
|
||||
|
||||

|
||||
|
||||
4. **Volume Stairs Patterns**: A similar concept, this time with volumes. Whenever a sequence of volume bars is found where each one is bigger than the previous one, they are bundled together in a "Stair". The same applies when they are going down (the next is smaller than the previous one). For a trading bot, this serves to identify if sell or buy volumes are raising or declining, if any.
|
||||
|
||||

|
||||
|
||||
5. **Bollinger Bands**: This is the traditional (Bollinger Bands indicator)[https://en.wikipedia.org/wiki/Bollinger_Bands]. Bollinger Bands have a moving average, in our case calculated with the last 20 periods (the line in the middle of the bands). We are plotting the moving average with one color when it is going up, and with a different color when it's going down. The upper band is at 2 Standard Deviations from the center, pretty much like the lower band, also at 2 Standard Deviations. These are the most widely used Bollinger Bands settings.
|
||||
|
||||

|
||||
|
||||
6. **Percentage Bandwidth or %B**: This is a well-known indicator that derives from the Bollinger Bands. In a nutshell it tells you how close the price is either to the upper band or the lower band at any point in time. When the price is in the middle of the bands (it is calculated with the close value of each candle), then %B is in the middle of its chart, at value 50. When the price touches the upper band, then %B is at 100, and finally when the price is at the lower band, then %B is at 0. The chart contains lines at %B value 30 and 70 since those are the most common values for traders to forecast when a reversal may happen. In our chart, %B is the one represented at #1. I've found useful to add a moving average in order to smooth volatility a bit, and to be able to ask—at any time—if it is going up or down. The moving average calculated with the last 5 %B values is plotted as line #2. Finally I also added a property called Bandwidth, which represents the separation of the upper band from the lower band. It is a measure of the volatility and is plotted at #3.
|
||||
|
||||

|
||||
|
||||
7. **Bollinger Channels**: This is a non-standard indicator derived from the Bollinger Bands. These types of channels are calculated using the Bollinger Bands moving average. Essentially an upward channel begins when the moving average turns from going down to going up, and the channel finishes when it turns from going up to down. A downward channel starts when the Bollinger Band moving average turns from going up to down, and it finishes when it starts going up again. Upward channels are plotted in green, while downward channels in red. Additional information can be found at the indicator's panel, like the number of periods contained at the channel.
|
||||
|
||||

|
||||
|
||||
8. **Bollinger Sub-Channels**: If we consider that one Bollinger Channel can have sub-channels with the same direction (up or down) but different slopes, then we get to the concept of Bollinger Sub-Channels. The most important property of a sub-channel is its slope. The possible values are: side, gentle, medium, high and extreme. With this information, a trading bot could easily ask if it is in a sub-channel with a certain slope and for how many periods.
|
||||
|
||||

|
||||
|
||||
#### Private Layers
|
||||
|
||||
1. **Trading Simulation**: The Trading Simulation layer displays a backtest + fordwardtest (paper trading) of whatever strategies you have created in the system. At sign up, you are provided with an initial set of strategies so that you can be up and running as quickly as possible. By activating the Trading Simulation layer you should be able to see something like this:
|
||||
|
||||

|
||||
|
||||
Let's take a moment to analyze what you see on the chart:
|
||||
|
||||
A. This shows you when you entered into one of your strategies (think of it as if the strategy was activated because when activation conditions were met). The first icon represents the moment when you entered into that particular strategy, and the second icon represents the moment you left the strategy.
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
|
||||
function drawScaleDisplay (label1, label2, xExtraOffSet1, xExtraOffSet2, container) {
|
||||
let fontSize1 = 20
|
||||
let fontSize2 = 10
|
||||
|
||||
const RED_LINE_HIGHT = 5
|
||||
const OPACITY = 1
|
||||
|
||||
let params = {
|
||||
cornerRadius: 3,
|
||||
lineWidth: RED_LINE_HIGHT,
|
||||
container: container,
|
||||
borderColor: UI_COLOR.RUSTED_RED,
|
||||
castShadow: false,
|
||||
backgroundColor: UI_COLOR.DARK,
|
||||
opacity: OPACITY
|
||||
}
|
||||
|
||||
roundedCornersBackground(params)
|
||||
|
||||
/* Place the Text */
|
||||
|
||||
let xOffset1 = label1.length * fontSize1 * FONT_ASPECT_RATIO
|
||||
|
||||
let labelPoint1 = {
|
||||
x: container.frame.width / 2 - xOffset1 + xExtraOffSet1,
|
||||
y: container.frame.height / 2 + 6
|
||||
}
|
||||
|
||||
labelPoint1 = container.frame.frameThisPoint(labelPoint1)
|
||||
|
||||
browserCanvasContext.font = fontSize1 + 'px ' + UI_FONT.PRIMARY
|
||||
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', 1)'
|
||||
|
||||
browserCanvasContext.fillText(label1, labelPoint1.x, labelPoint1.y)
|
||||
|
||||
let xOffset2 = label2.length * fontSize2 * FONT_ASPECT_RATIO
|
||||
|
||||
let labelPoint2 = {
|
||||
x: container.frame.width / 2 - xOffset2 / 2 - 3 + xExtraOffSet2,
|
||||
y: container.frame.height / 2 + 6
|
||||
}
|
||||
|
||||
labelPoint2 = container.frame.frameThisPoint(labelPoint2)
|
||||
|
||||
browserCanvasContext.font = fontSize2 + 'px ' + UI_FONT.PRIMARY
|
||||
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', 1)'
|
||||
|
||||
browserCanvasContext.fillText(label2, labelPoint2.x, labelPoint2.y)
|
||||
}
|
||||
+138
-147
@@ -1,17 +1,16 @@
|
||||
function newRateScale () {
|
||||
const MODULE_NAME = 'Right Scale'
|
||||
const INFO_LOG = false
|
||||
const INTENSIVE_LOG = false
|
||||
const ERROR_LOG = true
|
||||
const logger = newWebDebugLog()
|
||||
logger.fileName = MODULE_NAME
|
||||
|
||||
let thisObject = {
|
||||
heightPercentage: 100,
|
||||
container: undefined,
|
||||
rate: undefined,
|
||||
visible: true,
|
||||
physics: physics,
|
||||
draw: draw,
|
||||
getContainer: getContainer,
|
||||
initialize: initialize,
|
||||
heightPercentage: 100
|
||||
finalize: finalize
|
||||
}
|
||||
|
||||
const HEIGHT_PERCENTAGE_DEFAULT_VALUE = 50
|
||||
@@ -21,32 +20,26 @@ function newRateScale () {
|
||||
thisObject.container = newContainer()
|
||||
thisObject.container.initialize(MODULE_NAME)
|
||||
|
||||
thisObject.container.frame.width = viewPort.margins.RIGHT
|
||||
thisObject.container.frame.height = viewPort.visibleArea.bottomRight.y - viewPort.visibleArea.topRight.y
|
||||
|
||||
thisObject.container.frame.position.x = viewPort.visibleArea.bottomRight.x
|
||||
thisObject.container.frame.position.y = TOP_SPACE_HEIGHT
|
||||
|
||||
thisObject.container.isDraggeable = false
|
||||
thisObject.container.isClickeable = false
|
||||
thisObject.container.isWheelable = true
|
||||
thisObject.container.detectMouseOver = true
|
||||
|
||||
let mouse = {
|
||||
position: {
|
||||
x: 0,
|
||||
y: 0
|
||||
}
|
||||
}
|
||||
|
||||
let visible = false
|
||||
let timeLineCoordinateSystem
|
||||
thisObject.container.frame.width = 110
|
||||
thisObject.container.frame.height = 25
|
||||
|
||||
let isMouseOver
|
||||
return thisObject
|
||||
|
||||
function initialize (pTimeLineCoordinateSystem) {
|
||||
timeLineCoordinateSystem = pTimeLineCoordinateSystem
|
||||
function finalize () {
|
||||
thisObject.container.finalize()
|
||||
thisObject.container = undefined
|
||||
}
|
||||
|
||||
thisObject.container.eventHandler.listenToEvent('Mouse Wheel', onMouseWheel)
|
||||
function initialize () {
|
||||
thisObject.container.eventHandler.listenToEvent('onMouseWheel', onMouseWheel)
|
||||
thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver)
|
||||
thisObject.container.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver)
|
||||
|
||||
thisObject.heightPercentage = window.localStorage.getItem(MODULE_NAME)
|
||||
if (!thisObject.heightPercentage) {
|
||||
@@ -58,17 +51,14 @@ function newRateScale () {
|
||||
let event = {}
|
||||
event.heightPercentage = thisObject.heightPercentage
|
||||
thisObject.container.eventHandler.raiseEvent('Height Percentage Changed', event)
|
||||
}
|
||||
|
||||
thisObject.container.eventHandler.listenToEvent('onMouseOver', function (event) {
|
||||
mouse.position.x = event.x
|
||||
mouse.position.y = event.y
|
||||
function onMouseOver () {
|
||||
isMouseOver = true
|
||||
}
|
||||
|
||||
visible = true
|
||||
})
|
||||
|
||||
thisObject.container.eventHandler.listenToEvent('onMouseNotOver', function (event) {
|
||||
visible = false
|
||||
})
|
||||
function onMouseNotOver () {
|
||||
isMouseOver = false
|
||||
}
|
||||
|
||||
function onMouseWheel (event) {
|
||||
@@ -86,131 +76,132 @@ function newRateScale () {
|
||||
window.localStorage.setItem(MODULE_NAME, thisObject.heightPercentage)
|
||||
}
|
||||
|
||||
function getContainer (pPoint) {
|
||||
let container
|
||||
|
||||
/* In this case we manually frame this point since we do a very special treatment of the position of this scale. */
|
||||
let point = {
|
||||
x: 0,
|
||||
y: 0
|
||||
}
|
||||
point.x = pPoint.x - thisObject.container.frame.position.x - viewPort.margins.RIGHT
|
||||
point.y = pPoint.y - thisObject.container.frame.position.y
|
||||
|
||||
if (thisObject.container.frame.isThisPointHere(point, undefined, true) === true) {
|
||||
function getContainer (point) {
|
||||
if (thisObject.container.frame.isThisPointHere(point, true) === true) {
|
||||
return thisObject.container
|
||||
} else {
|
||||
/* This point does not belong to this space. */
|
||||
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
function physics () {
|
||||
|
||||
}
|
||||
|
||||
function draw () {
|
||||
if (visible === false) { return }
|
||||
drawRate()
|
||||
drawArrows()
|
||||
}
|
||||
|
||||
/* We need this scale to match the shape of its parent when the parent is inside the viewPort, when it is not, we need the scale still
|
||||
to be visible at the top of the viewPort. */
|
||||
function drawArrows () {
|
||||
if (isMouseOver !== true) { return }
|
||||
if (thisObject.visible === false || thisObject.rate === undefined) { return }
|
||||
|
||||
let frame = thisObject.container.parentContainer.frame
|
||||
let point1
|
||||
let point2
|
||||
let point3
|
||||
let point4
|
||||
const X_OFFSET = thisObject.container.frame.width / 2
|
||||
const Y_OFFSET = thisObject.container.frame.height / 2
|
||||
const HEIGHT = 6
|
||||
const WIDTH = 18
|
||||
const LINE_WIDTH = 3
|
||||
const OPACITY = 0.2
|
||||
const DISTANCE_BETWEEN_ARROWS = 10
|
||||
const MIN_DISTANCE_FROM_CENTER = 30
|
||||
const CURRENT_VALUE_DISTANCE = MIN_DISTANCE_FROM_CENTER + thisObject.heightPercentage
|
||||
const MAX_DISTANCE_FROM_CENTER = MIN_DISTANCE_FROM_CENTER + 115 + DISTANCE_BETWEEN_ARROWS
|
||||
|
||||
point1 = {
|
||||
x: frame.width - frame.width / 10,
|
||||
y: 0
|
||||
let ARROW_DIRECTION = 0
|
||||
|
||||
ARROW_DIRECTION = -1
|
||||
drawTwoArrows()
|
||||
ARROW_DIRECTION = 1
|
||||
drawTwoArrows()
|
||||
|
||||
function drawTwoArrows () {
|
||||
point1 = {
|
||||
x: X_OFFSET - WIDTH / 2,
|
||||
y: Y_OFFSET + DISTANCE_BETWEEN_ARROWS / 2 * ARROW_DIRECTION + CURRENT_VALUE_DISTANCE * ARROW_DIRECTION
|
||||
}
|
||||
|
||||
point2 = {
|
||||
x: X_OFFSET,
|
||||
y: Y_OFFSET + HEIGHT * ARROW_DIRECTION + DISTANCE_BETWEEN_ARROWS / 2 * ARROW_DIRECTION + CURRENT_VALUE_DISTANCE * ARROW_DIRECTION
|
||||
}
|
||||
|
||||
point3 = {
|
||||
x: X_OFFSET + WIDTH / 2,
|
||||
y: Y_OFFSET + DISTANCE_BETWEEN_ARROWS / 2 * ARROW_DIRECTION + CURRENT_VALUE_DISTANCE * ARROW_DIRECTION
|
||||
}
|
||||
|
||||
point1 = thisObject.container.frame.frameThisPoint(point1)
|
||||
point2 = thisObject.container.frame.frameThisPoint(point2)
|
||||
point3 = thisObject.container.frame.frameThisPoint(point3)
|
||||
|
||||
point4 = {
|
||||
x: X_OFFSET - WIDTH / 2,
|
||||
y: Y_OFFSET - DISTANCE_BETWEEN_ARROWS / 2 * ARROW_DIRECTION + CURRENT_VALUE_DISTANCE * ARROW_DIRECTION
|
||||
}
|
||||
|
||||
point5 = {
|
||||
x: X_OFFSET,
|
||||
y: Y_OFFSET + HEIGHT * ARROW_DIRECTION - DISTANCE_BETWEEN_ARROWS / 2 * ARROW_DIRECTION + CURRENT_VALUE_DISTANCE * ARROW_DIRECTION
|
||||
}
|
||||
|
||||
point6 = {
|
||||
x: X_OFFSET + WIDTH / 2,
|
||||
y: Y_OFFSET - DISTANCE_BETWEEN_ARROWS / 2 * ARROW_DIRECTION + CURRENT_VALUE_DISTANCE * ARROW_DIRECTION
|
||||
}
|
||||
|
||||
point4 = thisObject.container.frame.frameThisPoint(point4)
|
||||
point5 = thisObject.container.frame.frameThisPoint(point5)
|
||||
point6 = thisObject.container.frame.frameThisPoint(point6)
|
||||
|
||||
point7 = {
|
||||
x: X_OFFSET - WIDTH / 2,
|
||||
y: Y_OFFSET - DISTANCE_BETWEEN_ARROWS / 2 * ARROW_DIRECTION + MAX_DISTANCE_FROM_CENTER * ARROW_DIRECTION
|
||||
}
|
||||
|
||||
point8 = {
|
||||
x: X_OFFSET,
|
||||
y: Y_OFFSET - HEIGHT * ARROW_DIRECTION - DISTANCE_BETWEEN_ARROWS / 2 * ARROW_DIRECTION + MAX_DISTANCE_FROM_CENTER * ARROW_DIRECTION
|
||||
}
|
||||
|
||||
point9 = {
|
||||
x: X_OFFSET + WIDTH / 2,
|
||||
y: Y_OFFSET - DISTANCE_BETWEEN_ARROWS / 2 * ARROW_DIRECTION + MAX_DISTANCE_FROM_CENTER * ARROW_DIRECTION
|
||||
}
|
||||
|
||||
point7 = thisObject.container.frame.frameThisPoint(point7)
|
||||
point8 = thisObject.container.frame.frameThisPoint(point8)
|
||||
point9 = thisObject.container.frame.frameThisPoint(point9)
|
||||
|
||||
browserCanvasContext.setLineDash([0, 0])
|
||||
|
||||
browserCanvasContext.beginPath()
|
||||
|
||||
browserCanvasContext.moveTo(point1.x, point1.y)
|
||||
browserCanvasContext.lineTo(point2.x, point2.y)
|
||||
browserCanvasContext.lineTo(point3.x, point3.y)
|
||||
|
||||
browserCanvasContext.moveTo(point4.x, point4.y)
|
||||
browserCanvasContext.lineTo(point5.x, point5.y)
|
||||
browserCanvasContext.lineTo(point6.x, point6.y)
|
||||
|
||||
browserCanvasContext.moveTo(point7.x, point7.y)
|
||||
browserCanvasContext.lineTo(point8.x, point8.y)
|
||||
browserCanvasContext.lineTo(point9.x, point9.y)
|
||||
|
||||
browserCanvasContext.lineWidth = LINE_WIDTH
|
||||
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.DARK + ', ' + OPACITY + ')'
|
||||
browserCanvasContext.stroke()
|
||||
}
|
||||
}
|
||||
|
||||
point2 = {
|
||||
x: frame.width,
|
||||
y: 0
|
||||
}
|
||||
function drawRate () {
|
||||
if (thisObject.visible === false || thisObject.rate === undefined) { return }
|
||||
|
||||
point3 = {
|
||||
x: frame.width,
|
||||
y: frame.height
|
||||
}
|
||||
let label = (thisObject.rate - Math.trunc(thisObject.rate)).toFixed(2)
|
||||
let labelArray = label.split('.')
|
||||
let label1 = (Math.trunc(thisObject.rate)).toLocaleString()
|
||||
let label2 = labelArray[1]
|
||||
|
||||
point4 = {
|
||||
x: frame.width - frame.width / 10,
|
||||
y: frame.height
|
||||
}
|
||||
|
||||
point5 = {
|
||||
x: 0,
|
||||
y: 0
|
||||
}
|
||||
|
||||
/* Now the transformations. */
|
||||
|
||||
point1 = transformThisPoint(point1, frame.container)
|
||||
point2 = transformThisPoint(point2, frame.container)
|
||||
point3 = transformThisPoint(point3, frame.container)
|
||||
point4 = transformThisPoint(point4, frame.container)
|
||||
point5 = transformThisPoint(point5, frame.container)
|
||||
|
||||
point1 = viewPort.fitIntoVisibleArea(point1)
|
||||
point2 = viewPort.fitIntoVisibleArea(point2)
|
||||
point3 = viewPort.fitIntoVisibleArea(point3)
|
||||
point4 = viewPort.fitIntoVisibleArea(point4)
|
||||
point5 = viewPort.fitIntoVisibleArea(point5)
|
||||
|
||||
if (point2.x - point1.x < MIN_WIDTH) {
|
||||
point1.x = point2.x - MIN_WIDTH
|
||||
point4.x = point2.x - MIN_WIDTH
|
||||
}
|
||||
|
||||
/* Lets start the drawing. */
|
||||
/*
|
||||
browserCanvasContext.beginPath()
|
||||
browserCanvasContext.moveTo(point1.x, point1.y)
|
||||
browserCanvasContext.lineTo(point2.x + viewPort.margins.RIGHT, point2.y)
|
||||
browserCanvasContext.lineTo(point3.x + viewPort.margins.RIGHT, point3.y)
|
||||
browserCanvasContext.lineTo(point4.x, point4.y)
|
||||
browserCanvasContext.lineTo(point1.x, point1.y)
|
||||
browserCanvasContext.closePath()
|
||||
|
||||
browserCanvasContext.strokeStyle = 'rgba(150, 150, 150, 1)'
|
||||
browserCanvasContext.lineWidth = 1
|
||||
browserCanvasContext.stroke()
|
||||
*/
|
||||
thisObject.container.frame.position.x = point1.x
|
||||
thisObject.container.frame.position.y = point1.y
|
||||
|
||||
thisObject.container.frame.width = point2.x - point1.x
|
||||
thisObject.container.frame.height = point3.y - point2.y
|
||||
|
||||
let point = {
|
||||
x: point5.x + viewPort.margins.RIGHT,
|
||||
y: mouse.position.y
|
||||
}
|
||||
|
||||
let rate = getRateFromPoint(point, thisObject.container.parentContainer, timeLineCoordinateSystem)
|
||||
|
||||
let label = rate.toFixed(2)
|
||||
let fontSize = 10
|
||||
|
||||
let xOffset = label.length * fontSize * FONT_ASPECT_RATIO
|
||||
|
||||
if (point.y + fontSize / 2 > point3.y || point.y - fontSize / 2 < point1.y) { return }
|
||||
|
||||
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
|
||||
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.DARK + ', 0.50)'
|
||||
|
||||
browserCanvasContext.fillText(label, point1.x + viewPort.margins.RIGHT, point.y + fontSize / 2)
|
||||
|
||||
browserCanvasContext.beginPath()
|
||||
|
||||
browserCanvasContext.moveTo(point.x, point.y)
|
||||
browserCanvasContext.lineTo(point1.x + viewPort.margins.RIGHT, point.y)
|
||||
|
||||
browserCanvasContext.closePath()
|
||||
|
||||
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.DARK + ', 0.5)'
|
||||
browserCanvasContext.lineWidth = 0.2
|
||||
browserCanvasContext.setLineDash([1, 5])
|
||||
browserCanvasContext.stroke()
|
||||
drawScaleDisplay(label1, label2, 10, 40, thisObject.container)
|
||||
}
|
||||
}
|
||||
|
||||
+90
-55
@@ -1,17 +1,13 @@
|
||||
function newTimePeriodScale () {
|
||||
const MODULE_NAME = 'Time Period Scale'
|
||||
const INFO_LOG = false
|
||||
const INTENSIVE_LOG = false
|
||||
const ERROR_LOG = true
|
||||
const logger = newWebDebugLog()
|
||||
logger.fileName = MODULE_NAME
|
||||
|
||||
let thisObject = {
|
||||
timePeriod: undefined,
|
||||
container: undefined,
|
||||
draw: draw,
|
||||
getContainer: getContainer,
|
||||
initialize: initialize,
|
||||
timePeriod: undefined
|
||||
finalize: finalize
|
||||
}
|
||||
|
||||
const FILES_PERIOD_DEFAULT_VALUE = 0
|
||||
@@ -32,7 +28,7 @@ function newTimePeriodScale () {
|
||||
}
|
||||
}
|
||||
|
||||
let visible = false
|
||||
let visible = true
|
||||
let timeLineCoordinateSystem
|
||||
let objectStorage = {}
|
||||
let filePeriodIndex = FILES_PERIOD_DEFAULT_VALUE
|
||||
@@ -42,10 +38,15 @@ function newTimePeriodScale () {
|
||||
|
||||
return thisObject
|
||||
|
||||
function finalize () {
|
||||
thisObject.container.finalize()
|
||||
thisObject.container = undefined
|
||||
}
|
||||
|
||||
function initialize (pTimeLineCoordinateSystem) {
|
||||
timeLineCoordinateSystem = pTimeLineCoordinateSystem
|
||||
|
||||
thisObject.container.eventHandler.listenToEvent('Mouse Wheel', onMouseWheel)
|
||||
thisObject.container.eventHandler.listenToEvent('onMouseWheel', onMouseWheel)
|
||||
|
||||
readObjectState()
|
||||
newTimePeriod()
|
||||
@@ -78,6 +79,7 @@ function newTimePeriodScale () {
|
||||
}
|
||||
}
|
||||
}
|
||||
saveObjectState()
|
||||
newTimePeriod()
|
||||
}
|
||||
}
|
||||
@@ -133,6 +135,32 @@ function newTimePeriodScale () {
|
||||
}
|
||||
}
|
||||
|
||||
function saveObjectState () {
|
||||
objectStorage.filePeriodIndex = filePeriodIndex
|
||||
objectStorage.timePeriodIndex = timePeriodIndex
|
||||
window.localStorage.setItem(MODULE_NAME, JSON.stringify(objectStorage))
|
||||
}
|
||||
|
||||
function readObjectState () {
|
||||
let objectStorageString = window.localStorage.getItem(MODULE_NAME)
|
||||
if (objectStorageString !== null && objectStorageString !== '') {
|
||||
objectStorage = JSON.parse(objectStorageString)
|
||||
filePeriodIndex = objectStorage.filePeriodIndex
|
||||
timePeriodIndex = objectStorage.timePeriodIndex
|
||||
}
|
||||
}
|
||||
|
||||
function newTimePeriod () {
|
||||
let timePeriodArray = timePeriodsMasterArray[filePeriodIndex]
|
||||
thisObject.timePeriod = timePeriodArray[timePeriodIndex][0]
|
||||
timePeriodLabel = timePeriodArray[timePeriodIndex][1]
|
||||
|
||||
let event = {}
|
||||
event.timePeriod = thisObject.timePeriod
|
||||
thisObject.container.eventHandler.raiseEvent('Time Period Changed', event)
|
||||
window.localStorage.setItem('Current Time Period', JSON.stringify({filePeriodIndex: filePeriodIndex, timePeriodIndex: timePeriodIndex}))
|
||||
}
|
||||
|
||||
function draw () {
|
||||
if (visible === false) { return }
|
||||
|
||||
@@ -191,7 +219,7 @@ to be visible at the top of the viewPort. */
|
||||
|
||||
/* Lets start the drawing. */
|
||||
|
||||
let displacement = viewPort.margins.BOTTOM - BOTTOM_SPACE_HEIGHT
|
||||
let displacement = viewPort.margins.BOTTOM - COCKPIT_SPACE_HEIGHT
|
||||
|
||||
/*
|
||||
browserCanvasContext.beginPath()
|
||||
@@ -213,59 +241,66 @@ to be visible at the top of the viewPort. */
|
||||
thisObject.container.frame.width = point2.x - point1.x
|
||||
thisObject.container.frame.height = point3.y - point2.y
|
||||
|
||||
let point = {
|
||||
/* Common Variables */
|
||||
|
||||
let label = timePeriodLabel.split('-')
|
||||
let label1 = label[0]
|
||||
let label2 = label[1].toUpperCase()
|
||||
let fontSize1 = 20
|
||||
let fontSize2 = 10
|
||||
|
||||
const RED_LINE_HIGHT = 5
|
||||
const OPACITY = 1
|
||||
|
||||
let centerPoint = {
|
||||
x: mouse.position.x,
|
||||
y: point1.y + viewPort.margins.BOTTOM
|
||||
}
|
||||
|
||||
let label = timePeriodLabel
|
||||
let fontSize = 10
|
||||
let container = newContainer()
|
||||
container.initialize('Visible Time Scale')
|
||||
container.frame.width = 60
|
||||
container.frame.height = 25
|
||||
container.frame.position.x = centerPoint.x - container.frame.width / 2
|
||||
container.frame.position.y = centerPoint.y - container.frame.height / 2
|
||||
|
||||
let xOffset = label.length * fontSize * FONT_ASPECT_RATIO
|
||||
|
||||
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
|
||||
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.DARK + ', 0.50)'
|
||||
|
||||
if (point.x - xOffset / 2 < point1.x || point.x + xOffset / 2 > point2.x) { return }
|
||||
|
||||
browserCanvasContext.fillText(label, point.x - xOffset / 2, point.y + fontSize + 1)
|
||||
/*
|
||||
browserCanvasContext.beginPath()
|
||||
|
||||
browserCanvasContext.moveTo(point.x, point1.y)
|
||||
browserCanvasContext.lineTo(point.x, point5.y)
|
||||
|
||||
browserCanvasContext.closePath()
|
||||
|
||||
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.DARK + ', 0.5)'
|
||||
browserCanvasContext.lineWidth = 0.2
|
||||
browserCanvasContext.setLineDash([1, 5])
|
||||
browserCanvasContext.stroke()
|
||||
*/
|
||||
}
|
||||
|
||||
function saveObjectState () {
|
||||
objectStorage.filePeriodIndex = filePeriodIndex
|
||||
objectStorage.timePeriodIndex = timePeriodIndex
|
||||
window.localStorage.setItem(MODULE_NAME, JSON.stringify(objectStorage))
|
||||
}
|
||||
|
||||
function readObjectState () {
|
||||
let objectStorageString = window.localStorage.getItem(MODULE_NAME)
|
||||
if (objectStorageString !== null && objectStorageString !== '') {
|
||||
objectStorage = JSON.parse(objectStorageString)
|
||||
filePeriodIndex = objectStorage.filePeriodIndex
|
||||
timePeriodIndex = objectStorage.timePeriodIndex
|
||||
let params = {
|
||||
cornerRadius: 3,
|
||||
lineWidth: RED_LINE_HIGHT,
|
||||
container: container,
|
||||
borderColor: UI_COLOR.RUSTED_RED,
|
||||
castShadow: false,
|
||||
backgroundColor: UI_COLOR.DARK,
|
||||
opacity: OPACITY
|
||||
}
|
||||
}
|
||||
|
||||
function newTimePeriod () {
|
||||
let timePeriodArray = timePeriodsMasterArray[filePeriodIndex]
|
||||
thisObject.timePeriod = timePeriodArray[timePeriodIndex][0]
|
||||
timePeriodLabel = timePeriodArray[timePeriodIndex][1]
|
||||
roundedCornersBackground(params)
|
||||
|
||||
let event = {}
|
||||
event.timePeriod = thisObject.timePeriod
|
||||
thisObject.container.eventHandler.raiseEvent('Time Period Changed', event)
|
||||
/* Place the Text */
|
||||
|
||||
let xOffset1 = label1.length * fontSize1 * FONT_ASPECT_RATIO
|
||||
|
||||
let labelPoint1 = {
|
||||
x: mouse.position.x - xOffset1 / 2 - 14,
|
||||
y: point1.y + viewPort.margins.BOTTOM + 6
|
||||
}
|
||||
|
||||
browserCanvasContext.font = fontSize1 + 'px ' + UI_FONT.PRIMARY
|
||||
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', 1)'
|
||||
|
||||
browserCanvasContext.fillText(label1, labelPoint1.x, labelPoint1.y)
|
||||
|
||||
let xOffset2 = label2.length * fontSize2 * FONT_ASPECT_RATIO
|
||||
|
||||
let labelPoint2 = {
|
||||
x: mouse.position.x - xOffset2 / 2 - 3 + 14,
|
||||
y: point1.y + viewPort.margins.BOTTOM + 6
|
||||
}
|
||||
|
||||
browserCanvasContext.font = fontSize2 + 'px ' + UI_FONT.PRIMARY
|
||||
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', 1)'
|
||||
|
||||
browserCanvasContext.fillText(label2, labelPoint2.x, labelPoint2.y)
|
||||
}
|
||||
}
|
||||
|
||||
+138
-143
@@ -1,17 +1,16 @@
|
||||
function newTimeScale () {
|
||||
const MODULE_NAME = 'Time Scale'
|
||||
const INFO_LOG = false
|
||||
const INTENSIVE_LOG = false
|
||||
const ERROR_LOG = true
|
||||
const logger = newWebDebugLog()
|
||||
logger.fileName = MODULE_NAME
|
||||
|
||||
let thisObject = {
|
||||
lenghtPercentage: undefined,
|
||||
container: undefined,
|
||||
date: undefined,
|
||||
visible: true,
|
||||
physics: physics,
|
||||
draw: draw,
|
||||
getContainer: getContainer,
|
||||
initialize: initialize,
|
||||
lenghtPercentage: undefined
|
||||
finalize: finalize
|
||||
}
|
||||
|
||||
const LENGHT_PERCENTAGE_DEFAULT_VALUE = 5
|
||||
@@ -24,23 +23,23 @@ function newTimeScale () {
|
||||
thisObject.container.isDraggeable = false
|
||||
thisObject.container.isClickeable = false
|
||||
thisObject.container.isWheelable = true
|
||||
thisObject.container.detectMouseOver = true
|
||||
|
||||
let mouse = {
|
||||
position: {
|
||||
x: 0,
|
||||
y: 0
|
||||
}
|
||||
}
|
||||
|
||||
let visible = false
|
||||
let timeLineCoordinateSystem
|
||||
thisObject.container.frame.width = 190
|
||||
thisObject.container.frame.height = 25
|
||||
|
||||
let isMouseOver
|
||||
return thisObject
|
||||
|
||||
function initialize (pTimeLineCoordinateSystem) {
|
||||
timeLineCoordinateSystem = pTimeLineCoordinateSystem
|
||||
function finalize () {
|
||||
thisObject.container.finalize()
|
||||
thisObject.container = undefined
|
||||
}
|
||||
|
||||
thisObject.container.eventHandler.listenToEvent('Mouse Wheel', onMouseWheel)
|
||||
function initialize () {
|
||||
thisObject.container.eventHandler.listenToEvent('onMouseWheel', onMouseWheel)
|
||||
thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver)
|
||||
thisObject.container.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver)
|
||||
|
||||
thisObject.lenghtPercentage = window.localStorage.getItem(MODULE_NAME)
|
||||
if (!thisObject.lenghtPercentage) {
|
||||
@@ -52,17 +51,14 @@ function newTimeScale () {
|
||||
let event = {}
|
||||
event.lenghtPercentage = thisObject.lenghtPercentage
|
||||
thisObject.container.eventHandler.raiseEvent('Lenght Percentage Changed', event)
|
||||
}
|
||||
|
||||
thisObject.container.eventHandler.listenToEvent('onMouseOver', function (event) {
|
||||
mouse.position.x = event.x
|
||||
mouse.position.y = event.y
|
||||
function onMouseOver () {
|
||||
isMouseOver = true
|
||||
}
|
||||
|
||||
visible = true
|
||||
})
|
||||
|
||||
thisObject.container.eventHandler.listenToEvent('onMouseNotOver', function (event) {
|
||||
visible = false
|
||||
})
|
||||
function onMouseNotOver () {
|
||||
isMouseOver = false
|
||||
}
|
||||
|
||||
function onMouseWheel (event) {
|
||||
@@ -81,133 +77,132 @@ function newTimeScale () {
|
||||
window.localStorage.setItem(MODULE_NAME, thisObject.lenghtPercentage)
|
||||
}
|
||||
|
||||
function getContainer (pPoint) {
|
||||
let container
|
||||
|
||||
/* In this case we manually frame this point since we do a very special treatment of the position of this scale. */
|
||||
let point = {
|
||||
x: 0,
|
||||
y: 0
|
||||
}
|
||||
point.x = pPoint.x - thisObject.container.frame.position.x
|
||||
point.y = pPoint.y - thisObject.container.frame.position.y + viewPort.margins.TOP
|
||||
|
||||
if (thisObject.container.frame.isThisPointHere(point, undefined, true) === true) {
|
||||
function getContainer (point) {
|
||||
if (thisObject.container.frame.isThisPointHere(point, true) === true) {
|
||||
return thisObject.container
|
||||
} else {
|
||||
/* This point does not belong to this space. */
|
||||
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
function physics () {
|
||||
|
||||
}
|
||||
|
||||
function draw () {
|
||||
if (visible === false) { return }
|
||||
drawTime()
|
||||
drawArrows()
|
||||
}
|
||||
|
||||
/* We need this scale to match the shape of its parent when the parent is inside the viewPort, when it is not, we need the scale still
|
||||
to be visible at the top of the viewPort. */
|
||||
function drawArrows () {
|
||||
if (isMouseOver !== true) { return }
|
||||
if (thisObject.visible === false || thisObject.date === undefined) { return }
|
||||
|
||||
let frame = thisObject.container.parentContainer.frame
|
||||
let point1
|
||||
let point2
|
||||
let point3
|
||||
let point4
|
||||
const X_OFFSET = thisObject.container.frame.width / 2
|
||||
const Y_OFFSET = thisObject.container.frame.height / 2 - 10
|
||||
const HEIGHT = 18
|
||||
const WIDTH = 6
|
||||
const LINE_WIDTH = 3
|
||||
const OPACITY = 0.2
|
||||
const DISTANCE_BETWEEN_ARROWS = 10
|
||||
const MIN_DISTANCE_FROM_CENTER = 110
|
||||
const CURRENT_VALUE_DISTANCE = MIN_DISTANCE_FROM_CENTER + thisObject.lenghtPercentage
|
||||
const MAX_DISTANCE_FROM_CENTER = MIN_DISTANCE_FROM_CENTER + 100 + DISTANCE_BETWEEN_ARROWS
|
||||
|
||||
point1 = {
|
||||
x: 0,
|
||||
y: 0
|
||||
let ARROW_DIRECTION = 0
|
||||
|
||||
ARROW_DIRECTION = -1
|
||||
drawTwoArrows()
|
||||
ARROW_DIRECTION = 1
|
||||
drawTwoArrows()
|
||||
|
||||
function drawTwoArrows () {
|
||||
point1 = {
|
||||
x: X_OFFSET - WIDTH / 2 * ARROW_DIRECTION + DISTANCE_BETWEEN_ARROWS / 2 * ARROW_DIRECTION + CURRENT_VALUE_DISTANCE * ARROW_DIRECTION,
|
||||
y: Y_OFFSET - 0
|
||||
}
|
||||
|
||||
point2 = {
|
||||
x: X_OFFSET + WIDTH / 2 * ARROW_DIRECTION + DISTANCE_BETWEEN_ARROWS / 2 * ARROW_DIRECTION + CURRENT_VALUE_DISTANCE * ARROW_DIRECTION,
|
||||
y: Y_OFFSET + HEIGHT / 2
|
||||
}
|
||||
|
||||
point3 = {
|
||||
x: X_OFFSET - WIDTH / 2 * ARROW_DIRECTION + DISTANCE_BETWEEN_ARROWS / 2 * ARROW_DIRECTION + CURRENT_VALUE_DISTANCE * ARROW_DIRECTION,
|
||||
y: Y_OFFSET + HEIGHT
|
||||
}
|
||||
|
||||
point1 = thisObject.container.frame.frameThisPoint(point1)
|
||||
point2 = thisObject.container.frame.frameThisPoint(point2)
|
||||
point3 = thisObject.container.frame.frameThisPoint(point3)
|
||||
|
||||
point4 = {
|
||||
x: X_OFFSET - WIDTH / 2 * ARROW_DIRECTION - DISTANCE_BETWEEN_ARROWS / 2 * ARROW_DIRECTION + CURRENT_VALUE_DISTANCE * ARROW_DIRECTION,
|
||||
y: Y_OFFSET - 0
|
||||
}
|
||||
|
||||
point5 = {
|
||||
x: X_OFFSET + WIDTH / 2 * ARROW_DIRECTION - DISTANCE_BETWEEN_ARROWS / 2 * ARROW_DIRECTION + CURRENT_VALUE_DISTANCE * ARROW_DIRECTION,
|
||||
y: Y_OFFSET + HEIGHT / 2
|
||||
}
|
||||
|
||||
point6 = {
|
||||
x: X_OFFSET - WIDTH / 2 * ARROW_DIRECTION - DISTANCE_BETWEEN_ARROWS / 2 * ARROW_DIRECTION + CURRENT_VALUE_DISTANCE * ARROW_DIRECTION,
|
||||
y: Y_OFFSET + HEIGHT
|
||||
}
|
||||
|
||||
point4 = thisObject.container.frame.frameThisPoint(point4)
|
||||
point5 = thisObject.container.frame.frameThisPoint(point5)
|
||||
point6 = thisObject.container.frame.frameThisPoint(point6)
|
||||
|
||||
point7 = {
|
||||
x: X_OFFSET + WIDTH / 2 * ARROW_DIRECTION + DISTANCE_BETWEEN_ARROWS / 2 * ARROW_DIRECTION + MAX_DISTANCE_FROM_CENTER * ARROW_DIRECTION,
|
||||
y: Y_OFFSET - 0
|
||||
}
|
||||
|
||||
point8 = {
|
||||
x: X_OFFSET - WIDTH / 2 * ARROW_DIRECTION + DISTANCE_BETWEEN_ARROWS / 2 * ARROW_DIRECTION + MAX_DISTANCE_FROM_CENTER * ARROW_DIRECTION,
|
||||
y: Y_OFFSET + HEIGHT / 2
|
||||
}
|
||||
|
||||
point9 = {
|
||||
x: X_OFFSET + WIDTH / 2 * ARROW_DIRECTION + DISTANCE_BETWEEN_ARROWS / 2 * ARROW_DIRECTION + MAX_DISTANCE_FROM_CENTER * ARROW_DIRECTION,
|
||||
y: Y_OFFSET + HEIGHT
|
||||
}
|
||||
|
||||
point7 = thisObject.container.frame.frameThisPoint(point7)
|
||||
point8 = thisObject.container.frame.frameThisPoint(point8)
|
||||
point9 = thisObject.container.frame.frameThisPoint(point9)
|
||||
|
||||
browserCanvasContext.setLineDash([0, 0])
|
||||
|
||||
browserCanvasContext.beginPath()
|
||||
|
||||
browserCanvasContext.moveTo(point1.x, point1.y)
|
||||
browserCanvasContext.lineTo(point2.x, point2.y)
|
||||
browserCanvasContext.lineTo(point3.x, point3.y)
|
||||
|
||||
browserCanvasContext.moveTo(point4.x, point4.y)
|
||||
browserCanvasContext.lineTo(point5.x, point5.y)
|
||||
browserCanvasContext.lineTo(point6.x, point6.y)
|
||||
|
||||
browserCanvasContext.moveTo(point7.x, point7.y)
|
||||
browserCanvasContext.lineTo(point8.x, point8.y)
|
||||
browserCanvasContext.lineTo(point9.x, point9.y)
|
||||
|
||||
browserCanvasContext.lineWidth = LINE_WIDTH
|
||||
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.DARK + ', ' + OPACITY + ')'
|
||||
browserCanvasContext.stroke()
|
||||
}
|
||||
}
|
||||
|
||||
point2 = {
|
||||
x: frame.width,
|
||||
y: 0
|
||||
}
|
||||
function drawTime () {
|
||||
if (thisObject.visible === false || thisObject.date === undefined) { return }
|
||||
|
||||
point3 = {
|
||||
x: frame.width,
|
||||
y: frame.height / 10
|
||||
}
|
||||
let label = thisObject.date.toUTCString()
|
||||
let labelArray = label.split(' ')
|
||||
let label1 = labelArray[1] + ' ' + labelArray[2] + ' ' + labelArray[3]
|
||||
let label2 = labelArray[4]
|
||||
|
||||
point4 = {
|
||||
x: 0,
|
||||
y: frame.height / 10
|
||||
}
|
||||
|
||||
point5 = {
|
||||
x: 0,
|
||||
y: frame.height
|
||||
}
|
||||
|
||||
/* Now the transformations. */
|
||||
|
||||
point1 = transformThisPoint(point1, frame.container)
|
||||
point2 = transformThisPoint(point2, frame.container)
|
||||
point3 = transformThisPoint(point3, frame.container)
|
||||
point4 = transformThisPoint(point4, frame.container)
|
||||
point5 = transformThisPoint(point5, frame.container)
|
||||
|
||||
point1 = viewPort.fitIntoVisibleArea(point1)
|
||||
point2 = viewPort.fitIntoVisibleArea(point2)
|
||||
point3 = viewPort.fitIntoVisibleArea(point3)
|
||||
point4 = viewPort.fitIntoVisibleArea(point4)
|
||||
point5 = viewPort.fitIntoVisibleArea(point5)
|
||||
|
||||
if (point3.y - point2.y < MIN_HEIGHT) {
|
||||
point3.y = point2.y + MIN_HEIGHT
|
||||
point4.y = point2.y + MIN_HEIGHT
|
||||
}
|
||||
|
||||
/* Lets start the drawing. */
|
||||
/*
|
||||
browserCanvasContext.beginPath()
|
||||
browserCanvasContext.moveTo(point1.x, point1.y - viewPort.margins.TOP)
|
||||
browserCanvasContext.lineTo(point2.x, point2.y - viewPort.margins.TOP)
|
||||
browserCanvasContext.lineTo(point3.x, point3.y - viewPort.margins.TOP)
|
||||
browserCanvasContext.lineTo(point4.x, point4.y - viewPort.margins.TOP)
|
||||
browserCanvasContext.lineTo(point1.x, point1.y - viewPort.margins.TOP)
|
||||
browserCanvasContext.closePath()
|
||||
|
||||
browserCanvasContext.strokeStyle = 'rgba(150, 150, 150, 1)'
|
||||
browserCanvasContext.lineWidth = 1
|
||||
browserCanvasContext.stroke()
|
||||
*/
|
||||
|
||||
thisObject.container.frame.position.x = point1.x
|
||||
thisObject.container.frame.position.y = point1.y
|
||||
|
||||
thisObject.container.frame.width = point2.x - point1.x
|
||||
thisObject.container.frame.height = point3.y - point2.y
|
||||
|
||||
let point = {
|
||||
x: mouse.position.x,
|
||||
y: point1.y - viewPort.margins.TOP
|
||||
}
|
||||
|
||||
let date = getDateFromPoint(point, thisObject.container, timeLineCoordinateSystem)
|
||||
date = new Date(date)
|
||||
|
||||
let label = date.toUTCString()
|
||||
let fontSize = 10
|
||||
|
||||
let xOffset = label.length * fontSize * FONT_ASPECT_RATIO
|
||||
|
||||
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
|
||||
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.DARK + ', 0.50)'
|
||||
|
||||
if (point.x - xOffset / 2 < point1.x || point.x + xOffset / 2 > point2.x) { return }
|
||||
|
||||
browserCanvasContext.fillText(label, point.x - xOffset / 2, point.y + fontSize + 7)
|
||||
|
||||
browserCanvasContext.beginPath()
|
||||
|
||||
browserCanvasContext.moveTo(point.x, point1.y)
|
||||
browserCanvasContext.lineTo(point.x, point5.y)
|
||||
|
||||
browserCanvasContext.closePath()
|
||||
|
||||
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.DARK + ', 0.5)'
|
||||
browserCanvasContext.lineWidth = 0.2
|
||||
browserCanvasContext.setLineDash([1, 5])
|
||||
browserCanvasContext.stroke()
|
||||
drawScaleDisplay(label1, label2, 10, 60, thisObject.container)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
|
||||
function newBottomSpace () {
|
||||
let thisObject = {
|
||||
|
||||
container: undefined,
|
||||
draw: draw,
|
||||
getContainer: getContainer, // returns the inner most container that holds the point received by parameter.
|
||||
initialize: initialize
|
||||
}
|
||||
|
||||
var container = newContainer()
|
||||
container.initialize()
|
||||
thisObject.container = container
|
||||
|
||||
container.isDraggeable = false
|
||||
|
||||
resize()
|
||||
|
||||
return thisObject
|
||||
|
||||
function initialize () {
|
||||
window.canvasApp.eventHandler.listenToEvent('Browser Resized', resize)
|
||||
}
|
||||
|
||||
function resize () {
|
||||
container.frame.position.x = 0
|
||||
container.frame.position.y = viewPort.visibleArea.bottomLeft.y
|
||||
|
||||
thisObject.container.frame.width = browserCanvas.width
|
||||
thisObject.container.frame.height = BOTTOM_SPACE_HEIGHT
|
||||
}
|
||||
|
||||
function getContainer (point) {
|
||||
let container
|
||||
|
||||
return thisObject.container
|
||||
}
|
||||
|
||||
function draw () {
|
||||
thisObject.container.frame.draw(false, false)
|
||||
|
||||
drawBackground()
|
||||
}
|
||||
|
||||
function drawBackground () {
|
||||
let opacity = 1
|
||||
|
||||
let zeroPoint = {
|
||||
x: 0,
|
||||
y: 0
|
||||
}
|
||||
|
||||
zeroPoint = thisObject.container.frame.frameThisPoint(zeroPoint)
|
||||
|
||||
let breakpointsHeight = 15
|
||||
const RED_LINE_HIGHT = 5
|
||||
|
||||
browserCanvasContext.beginPath()
|
||||
browserCanvasContext.rect(zeroPoint.x, zeroPoint.y + breakpointsHeight, thisObject.container.frame.width, thisObject.container.frame.height)
|
||||
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.DARK + ', ' + opacity + ')'
|
||||
browserCanvasContext.closePath()
|
||||
browserCanvasContext.fill()
|
||||
|
||||
browserCanvasContext.beginPath()
|
||||
browserCanvasContext.rect(zeroPoint.x, zeroPoint.y + breakpointsHeight, thisObject.container.frame.width, RED_LINE_HIGHT)
|
||||
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.RUSTED_RED + ', ' + opacity + ')'
|
||||
browserCanvasContext.closePath()
|
||||
browserCanvasContext.fill()
|
||||
}
|
||||
}
|
||||
+144
-50
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
|
||||
The chart space is where all the charts live. What this space contains is a type of object we call Time Machine. A Time Machine is a cointainer of
|
||||
charts objects. The idea is simple, all the chart objects are ploted according to the time of the Time Machine object. When the time of the Time Machine
|
||||
@@ -8,16 +8,19 @@ changes, then all charts in it are replotted with the corresponging data.
|
||||
|
||||
function newChartSpace () {
|
||||
const MODULE_NAME = 'Chart Space'
|
||||
const INFO_LOG = false
|
||||
const ERROR_LOG = true
|
||||
const logger = newWebDebugLog()
|
||||
logger.fileName = MODULE_NAME
|
||||
|
||||
let thisObject = {
|
||||
visible: true,
|
||||
container: undefined,
|
||||
timeMachines: [],
|
||||
fitIntoVisibleArea: fitIntoVisibleArea,
|
||||
isThisPointVisible: isThisPointVisible,
|
||||
physics: physics,
|
||||
drawBackground: drawBackground,
|
||||
draw: draw,
|
||||
timeMachines: [],
|
||||
getContainer: getContainer, // returns the inner most container that holds the point received by parameter.
|
||||
initialize: initialize,
|
||||
finalize: finalize
|
||||
@@ -27,49 +30,39 @@ function newChartSpace () {
|
||||
thisObject.container.initialize(MODULE_NAME)
|
||||
|
||||
thisObject.container.isDraggeable = false
|
||||
thisObject.container.isWheelable = false
|
||||
|
||||
return thisObject
|
||||
|
||||
function finalize () {
|
||||
try {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] finalize -> Entering function.') }
|
||||
|
||||
for (let i = 0; i < thisObject.timeMachines.length; i++) {
|
||||
let timeMachine = thisObject.timeMachines[i]
|
||||
timeMachine.finalize()
|
||||
}
|
||||
} catch (err) {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] finalize -> err = ' + err.stack) }
|
||||
for (let i = 0; i < thisObject.timeMachines.length; i++) {
|
||||
let timeMachine = thisObject.timeMachines[i]
|
||||
timeMachine.finalize()
|
||||
}
|
||||
|
||||
thisObject.container.finalize()
|
||||
thisObject.container = undefined
|
||||
}
|
||||
|
||||
function initialize (callBackFunction) {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] initialize -> Entering function.') }
|
||||
|
||||
let initializedCounter = 0
|
||||
let toInitialize = 1
|
||||
|
||||
/* We create the first of many possible time machines that could live at the Chart Space. */
|
||||
/* We create the first of many possible time machines that could live at the Chart Space. */
|
||||
|
||||
var timeMachine = newTimeMachine()
|
||||
let timeMachine = newTimeMachine()
|
||||
|
||||
// timeMachine.container.connectToParent(thisObject.container, true, true)
|
||||
|
||||
/* We make the time machine a little bit smaller than the current space. */
|
||||
|
||||
timeMachine.container.frame.position.x = this.container.frame.width / 2 - timeMachine.container.frame.width / 2
|
||||
timeMachine.container.frame.position.y = this.container.frame.height / 2 - timeMachine.container.frame.height / 2
|
||||
/* We make the time machine a little bit smaller than the current space. */
|
||||
|
||||
timeMachine.container.frame.position.x = thisObject.container.frame.width / 2 - timeMachine.container.frame.width / 2
|
||||
timeMachine.container.frame.position.y = thisObject.container.frame.height / 2 - timeMachine.container.frame.height / 2
|
||||
timeMachine.container.fitFunction = fitIntoVisibleArea
|
||||
timeMachine.initialize(onTimeMachineInitialized)
|
||||
|
||||
function onTimeMachineInitialized (err) {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] initialize -> onTimeMachineInitialized -> Entering function.') }
|
||||
|
||||
initializedCounter++
|
||||
|
||||
if (err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] initialize -> onTimeMachineInitialized -> Initialization of a Time Machine failed.') }
|
||||
|
||||
callBackFunction(err)
|
||||
return
|
||||
}
|
||||
@@ -82,37 +75,138 @@ function newChartSpace () {
|
||||
}
|
||||
}
|
||||
|
||||
function getContainer (point, purpose) {
|
||||
if (thisObject.visible !== true) { return }
|
||||
|
||||
let container
|
||||
|
||||
/* Now we see which is the inner most container that has it */
|
||||
|
||||
for (let i = 0; i < thisObject.timeMachines.length; i++) {
|
||||
container = thisObject.timeMachines[i].getContainer(point, purpose)
|
||||
if (container !== undefined) {
|
||||
if (container.isForThisPurpose(purpose)) {
|
||||
if (thisObject.container.frame.isThisPointHere(point, true) === true) {
|
||||
return container
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (thisObject.container.frame.isThisPointHere(point, true) === true) {
|
||||
return thisObject.container
|
||||
} else {
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
function fitIntoVisibleArea (point) {
|
||||
/* Here we check the boundaries of the resulting points, so they dont go out of the visible area. */
|
||||
|
||||
let returnPoint = {
|
||||
x: point.x,
|
||||
y: point.y
|
||||
}
|
||||
|
||||
if (point.x > browserCanvas.width) {
|
||||
returnPoint.x = browserCanvas.width
|
||||
}
|
||||
|
||||
if (point.x < 0) {
|
||||
returnPoint.x = 0
|
||||
}
|
||||
|
||||
if (point.y > COCKPIT_SPACE_POSITION + COCKPIT_SPACE_HEIGHT / 2) {
|
||||
returnPoint.y = COCKPIT_SPACE_POSITION + COCKPIT_SPACE_HEIGHT / 2
|
||||
}
|
||||
|
||||
if (point.y < 0) {
|
||||
returnPoint.y = 0
|
||||
}
|
||||
|
||||
return returnPoint
|
||||
}
|
||||
|
||||
function isThisPointVisible (point) {
|
||||
if (point.x > browserCanvas.width) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (point.x < 0) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (point.y > COCKPIT_SPACE_POSITION + COCKPIT_SPACE_HEIGHT / 2) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (point.y < 0) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
function physics () {
|
||||
thisObjectPhysics()
|
||||
childrenPhysics()
|
||||
}
|
||||
|
||||
function thisObjectPhysics () {
|
||||
thisObject.container.frame.height = COCKPIT_SPACE_POSITION
|
||||
|
||||
if (thisObject.container.frame.height <= 0 / 100) {
|
||||
thisObject.visible = false
|
||||
} else {
|
||||
thisObject.visible = true
|
||||
}
|
||||
|
||||
viewPort.resize()
|
||||
}
|
||||
|
||||
function childrenPhysics () {
|
||||
for (let i = 0; i < thisObject.timeMachines.length; i++) {
|
||||
let timeMachine = thisObject.timeMachines[i]
|
||||
timeMachine.physics()
|
||||
}
|
||||
}
|
||||
|
||||
function drawBackground () {
|
||||
for (var i = 0; i < thisObject.timeMachines.length; i++) {
|
||||
var timeMachine = thisObject.timeMachines[i]
|
||||
if (thisObject.visible !== true) { return }
|
||||
|
||||
drawSpaceBackground()
|
||||
|
||||
for (let i = 0; i < thisObject.timeMachines.length; i++) {
|
||||
let timeMachine = thisObject.timeMachines[i]
|
||||
timeMachine.drawBackground()
|
||||
}
|
||||
}
|
||||
|
||||
function draw () {
|
||||
// thisObject.container.frame.draw(false, false)
|
||||
function drawSpaceBackground () {
|
||||
let opacity = '1'
|
||||
let fromPoint = {
|
||||
x: 0,
|
||||
y: 0
|
||||
}
|
||||
|
||||
for (var i = 0; i < thisObject.timeMachines.length; i++) {
|
||||
var timeMachine = thisObject.timeMachines[i]
|
||||
let toPoint = {
|
||||
x: browserCanvas.width,
|
||||
y: COCKPIT_SPACE_POSITION
|
||||
}
|
||||
|
||||
browserCanvasContext.beginPath()
|
||||
browserCanvasContext.rect(fromPoint.x, fromPoint.y, toPoint.x - fromPoint.x, toPoint.y - fromPoint.y)
|
||||
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + opacity + ')'
|
||||
browserCanvasContext.closePath()
|
||||
browserCanvasContext.fill()
|
||||
}
|
||||
|
||||
function draw () {
|
||||
if (thisObject.visible !== true) { return }
|
||||
|
||||
for (let i = 0; i < thisObject.timeMachines.length; i++) {
|
||||
let timeMachine = thisObject.timeMachines[i]
|
||||
timeMachine.draw()
|
||||
}
|
||||
}
|
||||
|
||||
function getContainer (point, purpose) {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] getContainer -> Entering function.') }
|
||||
|
||||
let container
|
||||
|
||||
/* Now we see which is the inner most container that has it */
|
||||
|
||||
for (var i = 0; i < this.timeMachines.length; i++) {
|
||||
container = this.timeMachines[i].getContainer(point, purpose)
|
||||
if (container !== undefined) {
|
||||
if (container.isForThisPurpose(purpose)) {
|
||||
return container
|
||||
}
|
||||
}
|
||||
}
|
||||
return this.container
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,251 @@
|
||||
|
||||
function newCockpitSpace () {
|
||||
const MODULE_NAME = 'CockpitSpace'
|
||||
|
||||
let thisObject = {
|
||||
container: undefined,
|
||||
status: 'BOTTOM',
|
||||
assetBalances: undefined,
|
||||
restartSimulation: undefined,
|
||||
draw: draw,
|
||||
physics: physics,
|
||||
getContainer: getContainer,
|
||||
finalize: finalize,
|
||||
initialize: initialize
|
||||
}
|
||||
|
||||
thisObject.container = newContainer()
|
||||
thisObject.container.initialize(MODULE_NAME)
|
||||
thisObject.container.isClickeable = false
|
||||
thisObject.container.detectMouseOver = true
|
||||
thisObject.container.isDraggeable = true
|
||||
thisObject.container.notDraggingOnX = true
|
||||
|
||||
controlsMap = new Map()
|
||||
resize()
|
||||
|
||||
let selfMouseClickEventSubscriptionId
|
||||
let canvasBrowserResizedEventSubscriptionId
|
||||
|
||||
return thisObject
|
||||
|
||||
function finalize () {
|
||||
thisObject.container.eventHandler.stopListening(selfMouseClickEventSubscriptionId)
|
||||
thisObject.container.eventHandler.stopListening(canvasBrowserResizedEventSubscriptionId)
|
||||
|
||||
thisObject.container.finalize()
|
||||
thisObject.container = undefined
|
||||
thisObject.assetBalances = undefined
|
||||
thisObject.restartSimulation = undefined
|
||||
}
|
||||
|
||||
function initialize () {
|
||||
canvasBrowserResizedEventSubscriptionId = window.canvasApp.eventHandler.listenToEvent('Browser Resized', resize)
|
||||
selfMouseClickEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick)
|
||||
|
||||
thisObject.assetBalances = newAssetBalances()
|
||||
thisObject.assetBalances.initialize()
|
||||
|
||||
thisObject.restartSimulation = newRestartSimulation()
|
||||
thisObject.restartSimulation.container.connectToParent(thisObject.container)
|
||||
thisObject.restartSimulation.initialize()
|
||||
}
|
||||
|
||||
function onMouseClick (event) {
|
||||
|
||||
}
|
||||
|
||||
function resize () {
|
||||
thisObject.container.frame.position.x = 0
|
||||
thisObject.container.frame.position.y = browserCanvas.height - COCKPIT_SPACE_HEIGHT
|
||||
|
||||
thisObject.container.frame.width = browserCanvas.width
|
||||
thisObject.container.frame.height = COCKPIT_SPACE_HEIGHT
|
||||
}
|
||||
|
||||
function physics () {
|
||||
thisObjectPhysics()
|
||||
childrenPhysics()
|
||||
}
|
||||
|
||||
function childrenPhysics () {
|
||||
thisObject.restartSimulation.physics()
|
||||
}
|
||||
function thisObjectPhysics () {
|
||||
/* Check the limits */
|
||||
|
||||
thisObject.status = 'MIDDLE'
|
||||
|
||||
let user = window.localStorage.getItem(LOGGED_IN_USER_LOCAL_STORAGE_KEY)
|
||||
if (user !== null) { // Only if user is logged in
|
||||
thisObject.container.isDraggeable = true
|
||||
} else {
|
||||
thisObject.container.isDraggeable = false
|
||||
}
|
||||
|
||||
if (thisObject.container.frame.position.y > browserCanvas.height * 99.5 / 100 - COCKPIT_SPACE_HEIGHT) {
|
||||
thisObject.container.frame.position.y = browserCanvas.height - COCKPIT_SPACE_HEIGHT
|
||||
thisObject.status = 'BOTTOM'
|
||||
canvas.strategySpace.makeInvisible()
|
||||
} else {
|
||||
canvas.strategySpace.makeVisible()
|
||||
}
|
||||
|
||||
if (thisObject.container.frame.position.y < browserCanvas.height * 0.5 / 100) {
|
||||
thisObject.container.frame.position.y = 0
|
||||
thisObject.status = 'TOP'
|
||||
canvas.panelsSpace.visible = false
|
||||
} else {
|
||||
canvas.panelsSpace.visible = true
|
||||
}
|
||||
|
||||
COCKPIT_SPACE_POSITION = thisObject.container.frame.position.y
|
||||
viewPort.resize()
|
||||
}
|
||||
|
||||
function getContainer (point) {
|
||||
let container
|
||||
|
||||
container = thisObject.restartSimulation.getContainer(point)
|
||||
if (container !== undefined) { return container }
|
||||
|
||||
if (thisObject.container.frame.isThisPointHere(point, true) === true) {
|
||||
return thisObject.container
|
||||
} else {
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
function draw () {
|
||||
thisObject.container.frame.draw(false, false)
|
||||
|
||||
drawBackground()
|
||||
|
||||
thisObject.assetBalances.draw()
|
||||
thisObject.restartSimulation.draw()
|
||||
}
|
||||
|
||||
function drawBackground () {
|
||||
let opacity = 1
|
||||
|
||||
let zeroPoint = {
|
||||
x: 0,
|
||||
y: 0
|
||||
}
|
||||
|
||||
const RED_LINE_HIGHT = 5
|
||||
|
||||
zeroPoint = thisObject.container.frame.frameThisPoint(zeroPoint)
|
||||
|
||||
browserCanvasContext.beginPath()
|
||||
browserCanvasContext.rect(zeroPoint.x, zeroPoint.y, thisObject.container.frame.width, thisObject.container.frame.height)
|
||||
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.DARK_TURQUOISE + ', ' + opacity + ')'
|
||||
browserCanvasContext.closePath()
|
||||
browserCanvasContext.fill()
|
||||
|
||||
browserCanvasContext.beginPath()
|
||||
browserCanvasContext.rect(zeroPoint.x, zeroPoint.y, thisObject.container.frame.width, RED_LINE_HIGHT)
|
||||
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.RUSTED_RED + ', ' + opacity + ')'
|
||||
browserCanvasContext.closePath()
|
||||
browserCanvasContext.fill()
|
||||
|
||||
browserCanvasContext.beginPath()
|
||||
browserCanvasContext.rect(zeroPoint.x, zeroPoint.y - RED_LINE_HIGHT + thisObject.container.frame.height, thisObject.container.frame.width, RED_LINE_HIGHT)
|
||||
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.RUSTED_RED + ', ' + opacity + ')'
|
||||
browserCanvasContext.closePath()
|
||||
browserCanvasContext.fill()
|
||||
|
||||
let user = window.localStorage.getItem(LOGGED_IN_USER_LOCAL_STORAGE_KEY)
|
||||
if (user !== null) { // Only if user is logged in
|
||||
arrow()
|
||||
}
|
||||
}
|
||||
|
||||
function arrow () {
|
||||
const X_OFFSET = thisObject.container.frame.width / 2
|
||||
const Y_OFFSET = thisObject.container.frame.height / 2
|
||||
const HEIGHT = 6
|
||||
const WIDTH = 18
|
||||
const LINE_WIDTH = 3
|
||||
const OPACITY = 1
|
||||
let DISTANCE_BETWEEN_ARROWS = 0
|
||||
let ARROW_1_DIRECTION = 0
|
||||
let ARROW_2_DIRECTION = 0
|
||||
|
||||
switch (thisObject.status) {
|
||||
|
||||
case ('TOP'): {
|
||||
ARROW_1_DIRECTION = -1
|
||||
ARROW_2_DIRECTION = -1
|
||||
DISTANCE_BETWEEN_ARROWS = 6
|
||||
break
|
||||
}
|
||||
case ('MIDDLE'): {
|
||||
ARROW_1_DIRECTION = 1
|
||||
ARROW_2_DIRECTION = -1
|
||||
DISTANCE_BETWEEN_ARROWS = 9
|
||||
break
|
||||
}
|
||||
case ('BOTTOM'): {
|
||||
ARROW_1_DIRECTION = 1
|
||||
ARROW_2_DIRECTION = 1
|
||||
DISTANCE_BETWEEN_ARROWS = 6
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
point1 = {
|
||||
x: X_OFFSET - WIDTH / 2,
|
||||
y: Y_OFFSET + HEIGHT / 2 * ARROW_1_DIRECTION - DISTANCE_BETWEEN_ARROWS / 2
|
||||
}
|
||||
|
||||
point2 = {
|
||||
x: X_OFFSET,
|
||||
y: Y_OFFSET - HEIGHT / 2 * ARROW_1_DIRECTION - DISTANCE_BETWEEN_ARROWS / 2
|
||||
}
|
||||
|
||||
point3 = {
|
||||
x: X_OFFSET + WIDTH / 2,
|
||||
y: Y_OFFSET + HEIGHT / 2 * ARROW_1_DIRECTION - DISTANCE_BETWEEN_ARROWS / 2
|
||||
}
|
||||
|
||||
point1 = thisObject.container.frame.frameThisPoint(point1)
|
||||
point2 = thisObject.container.frame.frameThisPoint(point2)
|
||||
point3 = thisObject.container.frame.frameThisPoint(point3)
|
||||
|
||||
point4 = {
|
||||
x: X_OFFSET - WIDTH / 2,
|
||||
y: Y_OFFSET + HEIGHT / 2 * ARROW_2_DIRECTION + DISTANCE_BETWEEN_ARROWS / 2
|
||||
}
|
||||
|
||||
point5 = {
|
||||
x: X_OFFSET,
|
||||
y: Y_OFFSET - HEIGHT / 2 * ARROW_2_DIRECTION + DISTANCE_BETWEEN_ARROWS / 2
|
||||
}
|
||||
|
||||
point6 = {
|
||||
x: X_OFFSET + WIDTH / 2,
|
||||
y: Y_OFFSET + HEIGHT / 2 * ARROW_2_DIRECTION + DISTANCE_BETWEEN_ARROWS / 2
|
||||
}
|
||||
|
||||
point4 = thisObject.container.frame.frameThisPoint(point4)
|
||||
point5 = thisObject.container.frame.frameThisPoint(point5)
|
||||
point6 = thisObject.container.frame.frameThisPoint(point6)
|
||||
|
||||
browserCanvasContext.setLineDash([0, 0])
|
||||
|
||||
browserCanvasContext.beginPath()
|
||||
|
||||
browserCanvasContext.moveTo(point1.x, point1.y)
|
||||
browserCanvasContext.lineTo(point2.x, point2.y)
|
||||
browserCanvasContext.lineTo(point3.x, point3.y)
|
||||
|
||||
browserCanvasContext.moveTo(point4.x, point4.y)
|
||||
browserCanvasContext.lineTo(point5.x, point5.y)
|
||||
browserCanvasContext.lineTo(point6.x, point6.y)
|
||||
|
||||
browserCanvasContext.lineWidth = LINE_WIDTH
|
||||
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + OPACITY + ')'
|
||||
browserCanvasContext.stroke()
|
||||
}
|
||||
}
|
||||
+131
-24
@@ -1,51 +1,158 @@
|
||||
|
||||
|
||||
function newFloatingSpace () {
|
||||
const MODULE_NAME = 'Floating Space'
|
||||
const INFO_LOG = false
|
||||
const ERROR_LOG = true
|
||||
/*
|
||||
The Floating Space is the place where floating elements like floatingObjects, live and are rendered.
|
||||
This space has its own physics which helps with the animation of these objects and also preventing them to overlap.
|
||||
*/
|
||||
/*
|
||||
The Floating Space is the place where floating elements like floatingObjects, live and are rendered.
|
||||
This space has its own physics which helps with the animation of these objects and also preventing them to overlap.
|
||||
*/
|
||||
|
||||
let thisObject = {
|
||||
floatingLayer: undefined, // This is the array of floatingObjects being displayed
|
||||
profileBalls: undefined,
|
||||
strategyPartConstructor: undefined,
|
||||
noteSets: undefined,
|
||||
container: undefined,
|
||||
fitIntoVisibleArea: fitIntoVisibleArea,
|
||||
isThisPointVisible: isThisPointVisible,
|
||||
makeVisible: makeVisible,
|
||||
makeInvisible: makeInvisible,
|
||||
draw: draw,
|
||||
physics: physics,
|
||||
getContainer: getContainer,
|
||||
initialize: initialize,
|
||||
finalize: finalize
|
||||
}
|
||||
|
||||
thisObject.container = newContainer()
|
||||
thisObject.container.initialize(MODULE_NAME)
|
||||
thisObject.container.isClickeable = false
|
||||
thisObject.container.isDraggeable = true
|
||||
thisObject.container.isWheelable = true
|
||||
thisObject.container.detectMouseOver = true
|
||||
thisObject.container.frame.radius = 0
|
||||
thisObject.container.frame.width = browserCanvas.width * 10
|
||||
thisObject.container.frame.height = browserCanvas.height * 10
|
||||
thisObject.container.frame.position.x = browserCanvas.width / 2 - thisObject.container.frame.width / 2
|
||||
thisObject.container.frame.position.y = browserCanvas.height / 2 - thisObject.container.frame.height / 2
|
||||
|
||||
let visible = false
|
||||
|
||||
return thisObject
|
||||
|
||||
function finalize () {
|
||||
try {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] finalize -> Entering function.') }
|
||||
|
||||
thisObject.floatingLayer.finalize()
|
||||
thisObject.profileBalls.finalize()
|
||||
} catch (err) {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] finalize -> err = ' + err.stack) }
|
||||
}
|
||||
thisObject.floatingLayer.finalize()
|
||||
thisObject.profileBalls.finalize()
|
||||
thisObject.strategyPartConstructor.finalize()
|
||||
thisObject.noteSets.finalize()
|
||||
}
|
||||
|
||||
function initialize (callBackFunction) {
|
||||
thisObject.floatingLayer = newFloatingLayer()
|
||||
thisObject.floatingLayer.initialize(onFloatingLayerInitialized)
|
||||
thisObject.floatingLayer.initialize()
|
||||
|
||||
function onFloatingLayerInitialized (err) {
|
||||
thisObject.profileBalls = newProfileBalls()
|
||||
thisObject.profileBalls.initialize(thisObject.floatingLayer, onProfileBallsInitialized)
|
||||
thisObject.profileBalls = newProfileBalls()
|
||||
thisObject.profileBalls.initialize(thisObject.floatingLayer)
|
||||
|
||||
function onProfileBallsInitialized (err) {
|
||||
thisObject.noteSets = newNoteSets()
|
||||
thisObject.noteSets.initialize(thisObject.floatingLayer, onNoteSetsInitialized)
|
||||
thisObject.noteSets = newNoteSets()
|
||||
thisObject.noteSets.initialize(thisObject.floatingLayer)
|
||||
|
||||
function onNoteSetsInitialized (err) {
|
||||
thisObject.strategyPartConstructor = newStrategyPartConstructor()
|
||||
thisObject.strategyPartConstructor.initialize(thisObject.floatingLayer)
|
||||
|
||||
}
|
||||
}
|
||||
thisObject.container.eventHandler.listenToEvent('onMouseWheel', onMouseWheel)
|
||||
}
|
||||
|
||||
function fitIntoVisibleArea (point) {
|
||||
/* Here we check the boundaries of the resulting points, so they dont go out of the visible area. */
|
||||
|
||||
let returnPoint = {
|
||||
x: point.x,
|
||||
y: point.y
|
||||
}
|
||||
|
||||
if (point.x > browserCanvas.width) {
|
||||
returnPoint.x = browserCanvas.width
|
||||
}
|
||||
|
||||
if (point.x < 0) {
|
||||
returnPoint.x = 0
|
||||
}
|
||||
|
||||
if (point.y < COCKPIT_SPACE_POSITION + COCKPIT_SPACE_HEIGHT) {
|
||||
returnPoint.y = COCKPIT_SPACE_POSITION + COCKPIT_SPACE_HEIGHT
|
||||
}
|
||||
|
||||
if (point.y > browserCanvas.height) {
|
||||
returnPoint.y = browserCanvas.height
|
||||
}
|
||||
|
||||
return returnPoint
|
||||
}
|
||||
|
||||
function isThisPointVisible (point) {
|
||||
if (point.x > browserCanvas.width) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (point.x < 0) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (point.y < COCKPIT_SPACE_POSITION + COCKPIT_SPACE_HEIGHT) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (point.y > browserCanvas.height) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
function onMouseWheel (event) {
|
||||
thisObject.floatingLayer.changeTargetRepulsion(event.wheelDelta)
|
||||
}
|
||||
|
||||
function makeVisible () {
|
||||
visible = true
|
||||
}
|
||||
|
||||
function makeInvisible () {
|
||||
visible = false
|
||||
}
|
||||
|
||||
function getContainer (point) {
|
||||
let container
|
||||
|
||||
container = thisObject.floatingLayer.getContainer(point)
|
||||
if (container !== undefined) { return container }
|
||||
|
||||
if (visible === true) {
|
||||
return thisObject.container
|
||||
}
|
||||
}
|
||||
|
||||
function physics () {
|
||||
thisObject.floatingLayer.physics()
|
||||
}
|
||||
|
||||
function draw () {
|
||||
if (visible === true) {
|
||||
drawBackground()
|
||||
}
|
||||
|
||||
thisObject.floatingLayer.draw()
|
||||
}
|
||||
|
||||
function drawBackground () {
|
||||
browserCanvasContext.beginPath()
|
||||
|
||||
browserCanvasContext.rect(thisObject.container.frame.position.x, thisObject.container.frame.position.y, thisObject.container.frame.width, thisObject.container.frame.height)
|
||||
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.BLACK + ', 1)'
|
||||
|
||||
browserCanvasContext.closePath()
|
||||
browserCanvasContext.fill()
|
||||
}
|
||||
}
|
||||
|
||||
+17
-4
@@ -6,6 +6,7 @@ The Panel Space y the place wehre all panels live, no matter who create them.
|
||||
|
||||
function newPanelsSpace () {
|
||||
let thisObject = {
|
||||
visible: true,
|
||||
container: undefined,
|
||||
createNewPanel: createNewPanel,
|
||||
destroyPanel: destroyPanel,
|
||||
@@ -16,7 +17,7 @@ function newPanelsSpace () {
|
||||
initialize: initialize
|
||||
}
|
||||
|
||||
var container = newContainer()
|
||||
let container = newContainer()
|
||||
container.initialize()
|
||||
thisObject.container = container
|
||||
thisObject.container.isDraggeable = false
|
||||
@@ -48,11 +49,15 @@ function newPanelsSpace () {
|
||||
case 'Products Panel':
|
||||
{
|
||||
panel = newProductsPanel()
|
||||
panel.fitFunction = canvas.chartSpace.fitIntoVisibleArea
|
||||
panel.container.isVisibleFunction = canvas.chartSpace.isThisPointVisible
|
||||
break
|
||||
}
|
||||
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.initialize()
|
||||
break
|
||||
}
|
||||
@@ -76,6 +81,10 @@ function newPanelsSpace () {
|
||||
let panel = thisObject.panels[i]
|
||||
|
||||
if (panel.handle === pPanelHandle) {
|
||||
if (panel.finalize !== undefined) {
|
||||
panel.finalize()
|
||||
}
|
||||
|
||||
thisObject.panels.splice(i, 1) // Delete item from array.
|
||||
return
|
||||
}
|
||||
@@ -96,11 +105,13 @@ function newPanelsSpace () {
|
||||
}
|
||||
|
||||
function draw () {
|
||||
if (thisObject.visible !== true) { return }
|
||||
|
||||
thisObject.container.frame.draw(false, false)
|
||||
|
||||
thisObject.panels = panelsMap.get('Global')
|
||||
if (thisObject.panels != undefined) {
|
||||
for (var i = 0; i < thisObject.panels.length; i++) {
|
||||
if (thisObject.panels !== undefined) {
|
||||
for (let i = 0; i < thisObject.panels.length; i++) {
|
||||
let panel = thisObject.panels[i]
|
||||
panel.draw()
|
||||
}
|
||||
@@ -108,7 +119,7 @@ function newPanelsSpace () {
|
||||
|
||||
thisObject.panels = panelsMap.get(window.CHART_ON_FOCUS)
|
||||
if (thisObject.panels !== undefined) {
|
||||
for (var i = 0; i < thisObject.panels.length; i++) {
|
||||
for (let i = 0; i < thisObject.panels.length; i++) {
|
||||
let panel = thisObject.panels[i]
|
||||
panel.draw()
|
||||
}
|
||||
@@ -116,6 +127,8 @@ function newPanelsSpace () {
|
||||
}
|
||||
|
||||
function getContainer (point) {
|
||||
if (thisObject.visible !== true) { return }
|
||||
|
||||
let container
|
||||
|
||||
/*
|
||||
|
||||
@@ -0,0 +1,166 @@
|
||||
|
||||
function newStrategySpace () {
|
||||
const MODULE_NAME = 'Strategy Space'
|
||||
let thisObject = {
|
||||
sidePanel: undefined,
|
||||
workplace: undefined,
|
||||
container: undefined,
|
||||
iconCollection: undefined,
|
||||
iconByPartType: undefined,
|
||||
draw: draw,
|
||||
getContainer: getContainer,
|
||||
makeVisible: makeVisible,
|
||||
makeInvisible: makeInvisible,
|
||||
initialize: initialize
|
||||
}
|
||||
|
||||
let container = newContainer()
|
||||
container.initialize()
|
||||
thisObject.container = container
|
||||
|
||||
container.isDraggeable = false
|
||||
|
||||
thisObject.iconCollection = new Map()
|
||||
thisObject.iconByPartType = new Map()
|
||||
|
||||
return thisObject
|
||||
|
||||
async function initialize () {
|
||||
thisObject.workplace = newWorkspace()
|
||||
|
||||
thisObject.workplace.initialize()
|
||||
await thisObject.workplace.loadFromStrategyzer()
|
||||
|
||||
loadIconCollection()
|
||||
buildIconByPartTypeMap()
|
||||
}
|
||||
|
||||
function buildIconByPartTypeMap () {
|
||||
const relationshipArray = [
|
||||
['Trading System', 'analysis'],
|
||||
['Strategy', 'quality'],
|
||||
['Strategy Entry Event', 'startup'],
|
||||
['Strategy Exit Event', 'support'],
|
||||
['Trade Entry Event', 'compass'],
|
||||
['Stop', 'pixel'],
|
||||
['Take Profit', 'competition'],
|
||||
['Phase', 'placeholder'],
|
||||
['Situation', 'attractive'],
|
||||
['Condition', 'testing']
|
||||
]
|
||||
|
||||
for (let i = 0; i < relationshipArray.length; i++) {
|
||||
let record = relationshipArray[i]
|
||||
let icon = thisObject.iconCollection.get(record[1])
|
||||
thisObject.iconByPartType.set(record[0], icon)
|
||||
}
|
||||
}
|
||||
|
||||
function loadIconCollection () {
|
||||
const iconsNames = [
|
||||
'analysis',
|
||||
'analysis-1',
|
||||
'approve',
|
||||
'attach',
|
||||
'attractive',
|
||||
'brainstorming',
|
||||
'broken-link',
|
||||
'chat',
|
||||
'chronometer',
|
||||
'compass',
|
||||
'competition',
|
||||
'content',
|
||||
'design-tool',
|
||||
'grid',
|
||||
'headphones',
|
||||
'html',
|
||||
'image',
|
||||
'layout',
|
||||
'loading',
|
||||
'login',
|
||||
'pantone',
|
||||
'paper-plane',
|
||||
'photo-camera',
|
||||
'piggy-bank',
|
||||
'pipette',
|
||||
'pixel',
|
||||
'placeholder',
|
||||
'planning',
|
||||
'promotion',
|
||||
'pyramid',
|
||||
'quality',
|
||||
'responsive',
|
||||
'schedule',
|
||||
'search',
|
||||
'security',
|
||||
'settings',
|
||||
'sitemap',
|
||||
'startup',
|
||||
'support',
|
||||
'tap',
|
||||
'target',
|
||||
'targeting',
|
||||
'task',
|
||||
'testing',
|
||||
'text',
|
||||
'timeline',
|
||||
'tools',
|
||||
'trash',
|
||||
'upload',
|
||||
'vector',
|
||||
'video-player'
|
||||
]
|
||||
|
||||
for (let i = 0; i < iconsNames.length; i++) {
|
||||
let name = iconsNames[i]
|
||||
loadImage(name)
|
||||
}
|
||||
|
||||
function loadImage (name) {
|
||||
const PATH = 'Images/Icons/style-01/'
|
||||
let image = new Image()
|
||||
image.onload = onImageLoad
|
||||
image.fileName = name
|
||||
|
||||
function onImageLoad () {
|
||||
image.canDrawIcon = true
|
||||
}
|
||||
image.src = window.canvasApp.urlPrefix + PATH + name + '.png'
|
||||
thisObject.iconCollection.set(name, image)
|
||||
}
|
||||
}
|
||||
|
||||
function makeVisible () {
|
||||
if (thisObject.workplace.isDeployed !== true) {
|
||||
thisObject.workplace.deploydTradingSystem()
|
||||
}
|
||||
canvas.floatingSpace.makeVisible()
|
||||
visible = true
|
||||
}
|
||||
|
||||
function makeInvisible () {
|
||||
visible = false
|
||||
}
|
||||
|
||||
function getContainer (point) {
|
||||
let container
|
||||
|
||||
if (thisObject.workplace !== undefined) {
|
||||
container = thisObject.workplace.getContainer(point)
|
||||
if (container !== undefined) { return container }
|
||||
}
|
||||
|
||||
if (thisObject.sidePanel !== undefined) {
|
||||
container = thisObject.sidePanel.getContainer(point)
|
||||
if (container !== undefined) { return container }
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
function draw () {
|
||||
if (thisObject.sidePanel !== undefined) {
|
||||
thisObject.sidePanel.draw()
|
||||
}
|
||||
}
|
||||
}
|
||||
Whitespace-only changes.
@@ -0,0 +1,87 @@
|
||||
const GRAPHQL_QUERY_GET_STRATEGIES = Apollo.gql`
|
||||
query($fbSlug: String!){
|
||||
|
||||
strategizer_StrategyByFb(fbSlug: $fbSlug){
|
||||
id
|
||||
subStrategies(activeOnly: true){
|
||||
name
|
||||
active
|
||||
entryPoint{
|
||||
situations{
|
||||
name
|
||||
conditions{
|
||||
name
|
||||
code
|
||||
}
|
||||
}
|
||||
}
|
||||
exitPoint{
|
||||
situations{
|
||||
name
|
||||
conditions{
|
||||
name
|
||||
code
|
||||
}
|
||||
}
|
||||
}
|
||||
sellPoint{
|
||||
situations{
|
||||
name
|
||||
conditions{
|
||||
name
|
||||
code
|
||||
}
|
||||
}
|
||||
}
|
||||
buyPoint{
|
||||
situations{
|
||||
name
|
||||
conditions{
|
||||
name
|
||||
code
|
||||
}
|
||||
}
|
||||
}
|
||||
stopLoss{
|
||||
phases{
|
||||
name
|
||||
code
|
||||
situations{
|
||||
name
|
||||
conditions{
|
||||
name
|
||||
code
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
buyOrder{
|
||||
phases{
|
||||
name
|
||||
code
|
||||
situations{
|
||||
name
|
||||
conditions{
|
||||
name
|
||||
code
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
sellOrder{
|
||||
phases{
|
||||
name
|
||||
code
|
||||
situations{
|
||||
name
|
||||
conditions{
|
||||
name
|
||||
code
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
Whitespace-only changes.
@@ -0,0 +1,7 @@
|
||||
const GRAPHQL_MUTATION_UPDATE_STRATEGIES = Apollo.gql`
|
||||
mutation strategizer_EditStrategy($id: ID!, $strategy: strategizer_StrategyInput!) {
|
||||
strategizer_EditStrategy(id: $id, strategy: $strategy) {
|
||||
id
|
||||
}
|
||||
}
|
||||
`
|
||||
@@ -0,0 +1,177 @@
|
||||
function newStrategyCollectionItem () {
|
||||
const MODULE_NAME = 'Strategy Collection Item'
|
||||
let thisObject = {
|
||||
icon: undefined,
|
||||
strategySource: undefined,
|
||||
strategy: undefined,
|
||||
container: undefined,
|
||||
draw: draw,
|
||||
getContainer: getContainer,
|
||||
initialize: initialize
|
||||
}
|
||||
|
||||
let isInitialized = false
|
||||
|
||||
thisObject.container = newContainer()
|
||||
thisObject.container.name = MODULE_NAME
|
||||
thisObject.container.initialize()
|
||||
thisObject.container.isClickeable = true
|
||||
thisObject.container.isDraggeable = false
|
||||
|
||||
let status = 'off'
|
||||
|
||||
return thisObject
|
||||
|
||||
function initialize (strategy) {
|
||||
thisObject.strategySource = strategy
|
||||
|
||||
const ITEM_WIDTH = SIDE_PANEL_WIDTH - 20
|
||||
const ITEM_HEIGHT = 80
|
||||
|
||||
thisObject.container.frame.width = ITEM_WIDTH
|
||||
thisObject.container.frame.height = ITEM_HEIGHT
|
||||
|
||||
const LEFT_MARGIN = (thisObject.container.parentContainer.frame.width - thisObject.container.frame.width) / 2
|
||||
const TOP_MARGIN = 100
|
||||
|
||||
thisObject.container.frame.position.x = LEFT_MARGIN
|
||||
thisObject.container.frame.position.y = TOP_MARGIN
|
||||
|
||||
thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick)
|
||||
isInitialized = true
|
||||
}
|
||||
|
||||
function onMouseClick (event) {
|
||||
if (status === 'off') {
|
||||
canvas.floatingSpace.makeVisible()
|
||||
thisObject.strategy = newTradingSystem()
|
||||
thisObject.strategy.initialize(thisObject.strategySource)
|
||||
status = 'on'
|
||||
} else {
|
||||
canvas.floatingSpace.makeInvisible()
|
||||
thisObject.strategy.finalize()
|
||||
status = 'off'
|
||||
}
|
||||
}
|
||||
|
||||
function getContainer (point) {
|
||||
let container
|
||||
if (thisObject.container.frame.isThisPointHere(point, true) === true) {
|
||||
return thisObject.container
|
||||
} else {
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
function draw () {
|
||||
if (isInitialized === false) { return }
|
||||
|
||||
borders()
|
||||
text()
|
||||
arrow()
|
||||
icon()
|
||||
}
|
||||
|
||||
function text () {
|
||||
if (thisObject.strategySource === undefined) {
|
||||
return
|
||||
}
|
||||
|
||||
const LEFT_MARGIN = 80
|
||||
const TOP_MARGIN = 45
|
||||
|
||||
let strategy = thisObject.strategySource
|
||||
|
||||
let labelpoint = {
|
||||
x: LEFT_MARGIN,
|
||||
y: TOP_MARGIN
|
||||
}
|
||||
|
||||
labelpoint = thisObject.container.frame.frameThisPoint(labelpoint)
|
||||
|
||||
let labelToPrint = strategy.name
|
||||
labelToPrint = ''
|
||||
labelToPrint = labelToPrint.substring(0, 30)
|
||||
let opacity = 1
|
||||
let fontSize = 15
|
||||
|
||||
printLabel(labelToPrint, labelpoint.x, labelpoint.y, opacity, fontSize)
|
||||
}
|
||||
|
||||
function borders () {
|
||||
let params = {
|
||||
cornerRadius: 8,
|
||||
lineWidth: 0.1,
|
||||
opacity: 1,
|
||||
container: thisObject.container,
|
||||
borderColor: UI_COLOR.DARK,
|
||||
backgroundColor: UI_COLOR.WHITE,
|
||||
castShadow: true
|
||||
}
|
||||
|
||||
roundedCornersBackground(params)
|
||||
}
|
||||
|
||||
function arrow () {
|
||||
const X_OFFSET = 400
|
||||
const Y_OFFSET = 40
|
||||
const HEIGHT = 12
|
||||
const WIDTH = 6
|
||||
const LINE_WIDTH = 2
|
||||
const OPACITY = 0.6
|
||||
|
||||
point1 = {
|
||||
x: X_OFFSET,
|
||||
y: Y_OFFSET - HEIGHT / 2
|
||||
}
|
||||
|
||||
point2 = {
|
||||
x: X_OFFSET + WIDTH,
|
||||
y: Y_OFFSET
|
||||
}
|
||||
|
||||
point3 = {
|
||||
x: X_OFFSET,
|
||||
y: Y_OFFSET + HEIGHT / 2
|
||||
}
|
||||
|
||||
/* Now the transformations. */
|
||||
|
||||
point1 = thisObject.container.frame.frameThisPoint(point1)
|
||||
point2 = thisObject.container.frame.frameThisPoint(point2)
|
||||
point3 = thisObject.container.frame.frameThisPoint(point3)
|
||||
|
||||
browserCanvasContext.setLineDash([0, 0])
|
||||
|
||||
/* The Arrow */
|
||||
|
||||
browserCanvasContext.beginPath()
|
||||
|
||||
browserCanvasContext.moveTo(point1.x, point1.y)
|
||||
browserCanvasContext.lineTo(point2.x, point2.y)
|
||||
browserCanvasContext.lineTo(point3.x, point3.y)
|
||||
|
||||
browserCanvasContext.lineWidth = LINE_WIDTH
|
||||
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.DARK + ', ' + OPACITY + ')'
|
||||
browserCanvasContext.stroke()
|
||||
}
|
||||
|
||||
function icon () {
|
||||
if (thisObject.icon === undefined) { return }
|
||||
|
||||
const X_OFFSET = 45
|
||||
const Y_OFFSET = 40
|
||||
const IMAGE_SIZE = 40
|
||||
|
||||
point1 = {
|
||||
x: X_OFFSET,
|
||||
y: Y_OFFSET
|
||||
}
|
||||
|
||||
/* Now the transformations. */
|
||||
|
||||
point1 = thisObject.container.frame.frameThisPoint(point1)
|
||||
|
||||
browserCanvasContext.drawImage(thisObject.icon, point1.x - IMAGE_SIZE / 2, point1.y - IMAGE_SIZE / 2, IMAGE_SIZE, IMAGE_SIZE)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,410 @@
|
||||
|
||||
function newTradingSystem () {
|
||||
const MODULE_NAME = 'Trading System'
|
||||
|
||||
let thisObject = {
|
||||
protocolData: undefined,
|
||||
container: undefined,
|
||||
getContainer: getContainer,
|
||||
initialize: initialize,
|
||||
finalize: finalize
|
||||
}
|
||||
|
||||
thisObject.container = newContainer()
|
||||
thisObject.container.initialize(MODULE_NAME)
|
||||
thisObject.container.isClickeable = false
|
||||
thisObject.container.isDraggeable = false
|
||||
thisObject.container.isWheelable = false
|
||||
thisObject.container.detectMouseOver = false
|
||||
thisObject.container.frame.radius = 0
|
||||
thisObject.container.frame.position.x = 0
|
||||
thisObject.container.frame.position.y = 0
|
||||
thisObject.container.frame.width = 0
|
||||
thisObject.container.frame.height = 0
|
||||
|
||||
return thisObject
|
||||
|
||||
function finalize () {
|
||||
destroyStrategyParts()
|
||||
thisObject.protocolData = undefined
|
||||
thisObject.container.finalize()
|
||||
thisObject.container = undefined
|
||||
}
|
||||
|
||||
function initialize (protocolData) {
|
||||
thisObject.protocolData = {
|
||||
id: protocolData.id,
|
||||
strategies: protocolData.subStrategies
|
||||
}
|
||||
generateStrategyParts()
|
||||
}
|
||||
|
||||
function getContainer (point) {
|
||||
|
||||
}
|
||||
|
||||
function createPart (partType, name, node, parentNode, chainParent, title) {
|
||||
let payload = {}
|
||||
if (chainParent === undefined) {
|
||||
payload.targetPosition = {
|
||||
x: canvas.floatingSpace.container.frame.width / 2,
|
||||
y: canvas.floatingSpace.container.frame.height / 2
|
||||
}
|
||||
} else {
|
||||
payload.targetPosition = {
|
||||
x: chainParent.payload.position.x,
|
||||
y: chainParent.payload.position.y
|
||||
}
|
||||
}
|
||||
|
||||
if (title !== undefined) {
|
||||
payload.subTitle = title
|
||||
} else {
|
||||
payload.subTitle = partType
|
||||
}
|
||||
|
||||
payload.visible = true
|
||||
payload.title = name
|
||||
payload.node = node
|
||||
payload.parentNode = parentNode
|
||||
payload.chainParent = chainParent
|
||||
payload.onMenuItemClick = onMenuItemClick
|
||||
|
||||
if (node.id === undefined) {
|
||||
node.id = newUniqueId()
|
||||
}
|
||||
node.payload = payload
|
||||
node.type = partType
|
||||
canvas.floatingSpace.strategyPartConstructor.createStrategyPart(payload)
|
||||
}
|
||||
|
||||
function destroyPart (node) {
|
||||
canvas.floatingSpace.strategyPartConstructor.destroyStrategyPart(node.payload)
|
||||
}
|
||||
|
||||
function generateStrategyParts () {
|
||||
let lastPhase
|
||||
let tradingSystem = thisObject.protocolData
|
||||
|
||||
createPart('Trading System', '', tradingSystem, undefined, undefined)
|
||||
|
||||
for (m = 0; m < tradingSystem.strategies.length; m++) {
|
||||
let strategy = tradingSystem.strategies[m]
|
||||
createPart('Strategy', strategy.name, strategy, tradingSystem, tradingSystem)
|
||||
|
||||
createPart('Strategy Entry Event', '', strategy.entryPoint, strategy, strategy)
|
||||
for (let k = 0; k < strategy.entryPoint.situations.length; k++) {
|
||||
let situation = strategy.entryPoint.situations[k]
|
||||
createPart('Situation', situation.name, situation, strategy.entryPoint, strategy.entryPoint, 'Strategy Entry' + ' ' + 'Situation')
|
||||
|
||||
for (let m = 0; m < situation.conditions.length; m++) {
|
||||
let condition = situation.conditions[m]
|
||||
createPart('Condition', condition.name, condition, situation, situation, 'Condition')
|
||||
}
|
||||
}
|
||||
|
||||
createPart('Strategy Exit Event', '', strategy.exitPoint, strategy, strategy)
|
||||
for (let k = 0; k < strategy.exitPoint.situations.length; k++) {
|
||||
let situation = strategy.exitPoint.situations[k]
|
||||
createPart('Situation', situation.name, situation, strategy.exitPoint, strategy.exitPoint, 'Strategy Exit' + ' ' + 'Situation')
|
||||
|
||||
for (let m = 0; m < situation.conditions.length; m++) {
|
||||
let condition = situation.conditions[m]
|
||||
createPart('Condition', condition.name, condition, situation, situation, 'Condition')
|
||||
}
|
||||
}
|
||||
|
||||
createPart('Trade Entry Event', '', strategy.sellPoint, strategy, strategy)
|
||||
for (let k = 0; k < strategy.sellPoint.situations.length; k++) {
|
||||
let situation = strategy.sellPoint.situations[k]
|
||||
createPart('Situation', situation.name, situation, strategy.sellPoint, strategy.sellPoint, 'Trade Entry' + ' ' + 'Situation')
|
||||
|
||||
for (let m = 0; m < situation.conditions.length; m++) {
|
||||
let condition = situation.conditions[m]
|
||||
createPart('Condition', condition.name, condition, situation, situation, 'Condition')
|
||||
}
|
||||
}
|
||||
|
||||
createPart('Stop', '', strategy.stopLoss, strategy, strategy)
|
||||
for (let p = 0; p < strategy.stopLoss.phases.length; p++) {
|
||||
let phase = strategy.stopLoss.phases[p]
|
||||
|
||||
let chainParent
|
||||
if (p === 0) {
|
||||
chainParent = strategy.stopLoss
|
||||
} else {
|
||||
chainParent = lastPhase
|
||||
}
|
||||
lastPhase = phase
|
||||
createPart('Phase', phase.name, phase, strategy.stopLoss, chainParent, 'Stop Phase')
|
||||
|
||||
for (let k = 0; k < phase.situations.length; k++) {
|
||||
let situation = phase.situations[k]
|
||||
createPart('Situation', situation.name, situation, phase, phase, 'Situation')
|
||||
|
||||
for (let m = 0; m < situation.conditions.length; m++) {
|
||||
let condition = situation.conditions[m]
|
||||
createPart('Condition', condition.name, condition, situation, situation, 'Condition')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
createPart('Take Profit', '', strategy.buyOrder, strategy, strategy)
|
||||
for (let p = 0; p < strategy.buyOrder.phases.length; p++) {
|
||||
let phase = strategy.buyOrder.phases[p]
|
||||
let chainParent
|
||||
if (p === 0) {
|
||||
chainParent = strategy.buyOrder
|
||||
} else {
|
||||
chainParent = lastPhase
|
||||
}
|
||||
lastPhase = phase
|
||||
createPart('Phase', phase.name, phase, strategy.buyOrder, chainParent, 'Take Profit Phase')
|
||||
|
||||
for (let k = 0; k < phase.situations.length; k++) {
|
||||
let situation = phase.situations[k]
|
||||
createPart('Situation', situation.name, situation, phase, phase, 'Situation')
|
||||
|
||||
for (let m = 0; m < situation.conditions.length; m++) {
|
||||
let condition = situation.conditions[m]
|
||||
createPart('Condition', condition.name, condition, situation, situation, 'Condition')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function destroyStrategyParts () {
|
||||
let strategy = thisObject.protocolData
|
||||
destroyPart(strategy)
|
||||
|
||||
destroyPart(strategy.entryPoint)
|
||||
for (let k = 0; k < strategy.entryPoint.situations.length; k++) {
|
||||
let situation = strategy.entryPoint.situations[k]
|
||||
destroyPart(situation)
|
||||
|
||||
for (let m = 0; m < situation.conditions.length; m++) {
|
||||
let condition = situation.conditions[m]
|
||||
destroyPart(condition)
|
||||
}
|
||||
}
|
||||
|
||||
destroyPart(strategy.exitPoint)
|
||||
for (let k = 0; k < strategy.exitPoint.situations.length; k++) {
|
||||
let situation = strategy.exitPoint.situations[k]
|
||||
destroyPart(situation)
|
||||
|
||||
for (let m = 0; m < situation.conditions.length; m++) {
|
||||
let condition = situation.conditions[m]
|
||||
destroyPart(condition)
|
||||
}
|
||||
}
|
||||
|
||||
destroyPart(strategy.sellPoint)
|
||||
for (let k = 0; k < strategy.sellPoint.situations.length; k++) {
|
||||
let situation = strategy.sellPoint.situations[k]
|
||||
destroyPart(situation)
|
||||
|
||||
for (let m = 0; m < situation.conditions.length; m++) {
|
||||
let condition = situation.conditions[m]
|
||||
destroyPart(condition)
|
||||
}
|
||||
}
|
||||
|
||||
destroyPart(strategy.stopLoss)
|
||||
for (let p = 0; p < strategy.stopLoss.phases.length; p++) {
|
||||
let phase = strategy.stopLoss.phases[p]
|
||||
destroyPart(strategy.stopLoss)
|
||||
|
||||
for (let k = 0; k < phase.situations.length; k++) {
|
||||
let situation = phase.situations[k]
|
||||
destroyPart(situation)
|
||||
|
||||
for (let m = 0; m < situation.conditions.length; m++) {
|
||||
let condition = situation.conditions[m]
|
||||
destroyPart(condition)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
destroyPart(strategy.buyOrder)
|
||||
for (let p = 0; p < strategy.buyOrder.phases.length; p++) {
|
||||
let phase = strategy.buyOrder.phases[p]
|
||||
destroyPart(strategy.buyOrder)
|
||||
|
||||
for (let k = 0; k < phase.situations.length; k++) {
|
||||
let situation = phase.situations[k]
|
||||
destroyPart(situation)
|
||||
|
||||
for (let m = 0; m < situation.conditions.length; m++) {
|
||||
let condition = situation.conditions[m]
|
||||
destroyPart(condition)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function onMenuItemClick (payload, action) {
|
||||
switch (action) {
|
||||
case 'Save Trading System':
|
||||
{
|
||||
let result = await canvas.strategySpace.workplace.saveToStrategyzer()
|
||||
return result
|
||||
break
|
||||
}
|
||||
|
||||
case 'Open Settings':
|
||||
break
|
||||
case 'Delete Strategy':
|
||||
|
||||
break
|
||||
|
||||
case 'Reload Strategy':
|
||||
|
||||
break
|
||||
|
||||
case 'Save Strategy':
|
||||
|
||||
break
|
||||
|
||||
case 'Edit Code':
|
||||
|
||||
break
|
||||
case 'Add Phase':
|
||||
{
|
||||
let phaseParent = payload.node
|
||||
let m = phaseParent.phases.length
|
||||
let phase = {
|
||||
name: 'New Phase',
|
||||
code: '',
|
||||
situations: []
|
||||
}
|
||||
phaseParent.phases.push(phase)
|
||||
let phaseChainParent
|
||||
if (m > 0) {
|
||||
phaseChainParent = phaseParent.phases[m - 1]
|
||||
} else {
|
||||
phaseChainParent = phaseParent
|
||||
}
|
||||
createPart('Phase', phase.name, phase, phaseParent, phaseChainParent, 'Phase')
|
||||
}
|
||||
break
|
||||
case 'Add Situation':
|
||||
{
|
||||
let phase = payload.node
|
||||
let m = phase.situations.length
|
||||
let situation = {
|
||||
name: 'New Situation',
|
||||
conditions: []
|
||||
}
|
||||
phase.situations.push(situation)
|
||||
createPart('Situation', situation.name, situation, phase, phase, 'Situation')
|
||||
}
|
||||
break
|
||||
case 'Add Condition':
|
||||
{
|
||||
let situation = payload.node
|
||||
let m = situation.conditions.length
|
||||
let condition = {
|
||||
name: 'New Condition',
|
||||
code: ''
|
||||
}
|
||||
situation.conditions.push(condition)
|
||||
createPart('Condition', condition.name, condition, situation, situation, 'Condition')
|
||||
}
|
||||
break
|
||||
case 'Delete Phase': {
|
||||
deletePhase(payload.node)
|
||||
break
|
||||
}
|
||||
case 'Delete Situation': {
|
||||
deleteSituation(payload.node)
|
||||
break
|
||||
}
|
||||
case 'Delete Condition': {
|
||||
deleteCondition(payload.node)
|
||||
break
|
||||
}
|
||||
default:
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function deletePhase (node) {
|
||||
let payload = node.payload
|
||||
for (let k = 0; k < payload.parentNode.phases.length; k++) {
|
||||
let phase = payload.parentNode.phases[k]
|
||||
if (phase.id === node.id) {
|
||||
for (let j = 0; j < phase.situations.length; j++) {
|
||||
let situation = phase.situations[j]
|
||||
for (let i = 0; i < situation.conditions.length; i++) {
|
||||
let condition = situation.conditions[i]
|
||||
destroyPart(condition)
|
||||
cleanNode(condition)
|
||||
}
|
||||
situation.conditions = []
|
||||
destroyPart(situation)
|
||||
phase.situations.splice(j, 1)
|
||||
cleanNode(situation)
|
||||
}
|
||||
phase.situations = []
|
||||
/* Before deleting this phase we need to give its chainParent to the next phase down the chain */
|
||||
if (k < payload.parentNode.phases.length - 1) {
|
||||
payload.parentNode.phases[k + 1].payload.chainParent = payload.chainParent
|
||||
}
|
||||
/* Continue destroying this phase */
|
||||
destroyPart(phase)
|
||||
payload.parentNode.phases.splice(k, 1)
|
||||
cleanNode(phase)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function deleteSituation (node) {
|
||||
let payload = node.payload
|
||||
for (let j = 0; j < payload.parentNode.situations.length; j++) {
|
||||
let situation = payload.parentNode.situations[j]
|
||||
if (situation.id === node.id) {
|
||||
for (let i = 0; i < situation.conditions.length; i++) {
|
||||
let condition = situation.conditions[i]
|
||||
destroyPart(condition)
|
||||
cleanNode(condition)
|
||||
}
|
||||
situation.conditions = []
|
||||
destroyPart(situation)
|
||||
payload.parentNode.situations.splice(j, 1)
|
||||
cleanNode(situation)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function deleteCondition (node) {
|
||||
let payload = node.payload
|
||||
for (let i = 0; i < payload.parentNode.conditions.length; i++) {
|
||||
let condition = payload.parentNode.conditions[i]
|
||||
if (condition.id === node.id) {
|
||||
destroyPart(node)
|
||||
payload.parentNode.conditions.splice(i, 1)
|
||||
cleanNode(condition)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function cleanNode (node) {
|
||||
node.payload.targetPosition.x = undefined
|
||||
node.payload.targetPosition.y = undefined
|
||||
node.payload.visible = undefined
|
||||
node.payload.subTitle = undefined
|
||||
node.payload.title = undefined
|
||||
node.payload.node = undefined
|
||||
node.payload.parentNode = undefined
|
||||
node.payload.chainParent = undefined
|
||||
node.payload.onMenuItemClick = undefined
|
||||
node.handle = undefined
|
||||
node.payload = undefined
|
||||
node.cleaned = true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,359 @@
|
||||
|
||||
function newWorkspace () {
|
||||
const MODULE_NAME = 'Workspace'
|
||||
const ERROR_LOG = true
|
||||
const logger = newWebDebugLog()
|
||||
logger.fileName = MODULE_NAME
|
||||
|
||||
let thisObject = {
|
||||
isDeployed: false,
|
||||
strategizerData: undefined,
|
||||
container: undefined,
|
||||
tradingSystem: undefined,
|
||||
loadFromStrategyzer: loadFromStrategyzer,
|
||||
saveToStrategyzer: saveToStrategyzer,
|
||||
deploydTradingSystem: deploydTradingSystem,
|
||||
draw: draw,
|
||||
getContainer: getContainer,
|
||||
initialize: initialize
|
||||
}
|
||||
|
||||
let colletionItems = []
|
||||
|
||||
thisObject.container = newContainer()
|
||||
thisObject.container.name = MODULE_NAME
|
||||
thisObject.container.initialize()
|
||||
|
||||
thisObject.container.frame.width = 0
|
||||
thisObject.container.frame.height = 0
|
||||
|
||||
thisObject.container.frame.position.x = 0
|
||||
thisObject.container.frame.position.y = 0
|
||||
|
||||
thisObject.container.isDraggeable = false
|
||||
thisObject.container.isClickeable = false
|
||||
|
||||
return thisObject
|
||||
|
||||
function initialize () {
|
||||
|
||||
}
|
||||
|
||||
async function saveToStrategyzer () {
|
||||
try {
|
||||
const accessToken = window.localStorage.getItem(LOGGED_IN_ACCESS_TOKEN_LOCAL_STORAGE_KEY)
|
||||
|
||||
let user = window.localStorage.getItem(LOGGED_IN_USER_LOCAL_STORAGE_KEY)
|
||||
if (user === null) {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] saveToStrategyzer -> Can not save because user is not logged in. ') }
|
||||
return
|
||||
}
|
||||
|
||||
user = JSON.parse(user)
|
||||
|
||||
const authId = user.authId
|
||||
|
||||
const apolloClient = new Apollo.lib.ApolloClient({
|
||||
networkInterface: Apollo.lib.createNetworkInterface({
|
||||
uri: window.canvasApp.graphQL.masterAppApiUrl,
|
||||
transportBatching: true
|
||||
}),
|
||||
connectToDevTools: true
|
||||
})
|
||||
|
||||
/* Updating all Strategies */
|
||||
|
||||
const networkInterface = Apollo.lib.createNetworkInterface({
|
||||
uri: window.canvasApp.graphQL.masterAppApiUrl
|
||||
})
|
||||
|
||||
networkInterface.use([{
|
||||
applyMiddleware (req, next) {
|
||||
req.options.headers = {
|
||||
authorization: `Bearer ${accessToken}`
|
||||
}
|
||||
next()
|
||||
}
|
||||
}])
|
||||
|
||||
let dataToSave = buildGraphQLDataToSave()
|
||||
|
||||
const updateStrategies = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
apolloClient.mutate({
|
||||
mutation: GRAPHQL_MUTATION_UPDATE_STRATEGIES,
|
||||
variables: {
|
||||
id: thisObject.strategizerData.id,
|
||||
strategy: dataToSave.strategy
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
resolve(true)
|
||||
})
|
||||
.catch(err => {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] saveToStrategyzer -> ApolloClient error updating user strategies -> err = ' + err.stack) }
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
let result = await updateStrategies()
|
||||
|
||||
return result
|
||||
} catch (err) {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] saveToStrategyzer -> err = ' + err.stack) }
|
||||
}
|
||||
}
|
||||
|
||||
function buildGraphQLDataToSave () {
|
||||
let graphQL_Mutation = ''
|
||||
|
||||
let dataToSave = {
|
||||
strategy: {
|
||||
subStrategies: []
|
||||
}
|
||||
}
|
||||
|
||||
for (m = 0; m < thisObject.tradingSystem.protocolData.strategies.length; m++) {
|
||||
let workspaceStrategy = thisObject.tradingSystem.protocolData.strategies[m]
|
||||
let strategy = {
|
||||
name: workspaceStrategy.name,
|
||||
active: workspaceStrategy.active,
|
||||
entryPoint: {
|
||||
situations: []
|
||||
},
|
||||
exitPoint: {
|
||||
situations: []
|
||||
},
|
||||
sellPoint: {
|
||||
situations: []
|
||||
},
|
||||
stopLoss: {
|
||||
phases: []
|
||||
},
|
||||
buyOrder: {
|
||||
phases: []
|
||||
}
|
||||
}
|
||||
|
||||
for (let k = 0; k < workspaceStrategy.entryPoint.situations.length; k++) {
|
||||
let workspaceSituation = workspaceStrategy.entryPoint.situations[k]
|
||||
let situation = {
|
||||
name: workspaceSituation.name,
|
||||
conditions: []
|
||||
}
|
||||
|
||||
for (let m = 0; m < workspaceSituation.conditions.length; m++) {
|
||||
let workspaceCondition = workspaceSituation.conditions[m]
|
||||
let condition = {
|
||||
name: workspaceCondition.name,
|
||||
code: workspaceCondition.code
|
||||
}
|
||||
situation.conditions.push(condition)
|
||||
}
|
||||
strategy.entryPoint.situations.push(situation)
|
||||
}
|
||||
|
||||
for (let k = 0; k < workspaceStrategy.exitPoint.situations.length; k++) {
|
||||
let workspaceSituation = workspaceStrategy.exitPoint.situations[k]
|
||||
let situation = {
|
||||
name: workspaceSituation.name,
|
||||
conditions: []
|
||||
}
|
||||
|
||||
for (let m = 0; m < workspaceSituation.conditions.length; m++) {
|
||||
let workspaceCondition = workspaceSituation.conditions[m]
|
||||
let condition = {
|
||||
name: workspaceCondition.name,
|
||||
code: workspaceCondition.code
|
||||
}
|
||||
situation.conditions.push(condition)
|
||||
}
|
||||
strategy.exitPoint.situations.push(situation)
|
||||
}
|
||||
|
||||
for (let k = 0; k < workspaceStrategy.sellPoint.situations.length; k++) {
|
||||
let workspaceSituation = workspaceStrategy.sellPoint.situations[k]
|
||||
let situation = {
|
||||
name: workspaceSituation.name,
|
||||
conditions: []
|
||||
}
|
||||
|
||||
for (let m = 0; m < workspaceSituation.conditions.length; m++) {
|
||||
let workspaceCondition = workspaceSituation.conditions[m]
|
||||
let condition = {
|
||||
name: workspaceCondition.name,
|
||||
code: workspaceCondition.code
|
||||
}
|
||||
situation.conditions.push(condition)
|
||||
}
|
||||
strategy.sellPoint.situations.push(situation)
|
||||
}
|
||||
|
||||
for (let p = 0; p < workspaceStrategy.stopLoss.phases.length; p++) {
|
||||
let workspacePhase = workspaceStrategy.stopLoss.phases[p]
|
||||
let phase = {
|
||||
name: workspacePhase.name,
|
||||
code: workspacePhase.code,
|
||||
situations: []
|
||||
}
|
||||
|
||||
for (let k = 0; k < workspacePhase.situations.length; k++) {
|
||||
let workspaceSituation = workspacePhase.situations[k]
|
||||
let situation = {
|
||||
name: workspaceSituation.name,
|
||||
conditions: []
|
||||
}
|
||||
|
||||
for (let m = 0; m < workspaceSituation.conditions.length; m++) {
|
||||
let workspaceCondition = workspaceSituation.conditions[m]
|
||||
let condition = {
|
||||
name: workspaceCondition.name,
|
||||
code: workspaceCondition.code
|
||||
}
|
||||
situation.conditions.push(condition)
|
||||
}
|
||||
phase.situations.push(situation)
|
||||
}
|
||||
strategy.stopLoss.phases.push(phase)
|
||||
}
|
||||
|
||||
for (let p = 0; p < workspaceStrategy.buyOrder.phases.length; p++) {
|
||||
let workspacePhase = workspaceStrategy.buyOrder.phases[p]
|
||||
let phase = {
|
||||
name: workspacePhase.name,
|
||||
code: workspacePhase.code,
|
||||
situations: []
|
||||
}
|
||||
|
||||
for (let k = 0; k < workspacePhase.situations.length; k++) {
|
||||
let workspaceSituation = workspacePhase.situations[k]
|
||||
let situation = {
|
||||
name: workspaceSituation.name,
|
||||
conditions: []
|
||||
}
|
||||
|
||||
for (let m = 0; m < workspaceSituation.conditions.length; m++) {
|
||||
let workspaceCondition = workspaceSituation.conditions[m]
|
||||
let condition = {
|
||||
name: workspaceCondition.name,
|
||||
code: workspaceCondition.code
|
||||
}
|
||||
situation.conditions.push(condition)
|
||||
}
|
||||
phase.situations.push(situation)
|
||||
}
|
||||
strategy.buyOrder.phases.push(phase)
|
||||
}
|
||||
dataToSave.strategy.subStrategies.push(strategy)
|
||||
}
|
||||
|
||||
return dataToSave
|
||||
}
|
||||
|
||||
async function loadFromStrategyzer () {
|
||||
try {
|
||||
const accessToken = window.localStorage.getItem(LOGGED_IN_ACCESS_TOKEN_LOCAL_STORAGE_KEY)
|
||||
|
||||
let user = window.localStorage.getItem(LOGGED_IN_USER_LOCAL_STORAGE_KEY)
|
||||
if (user === null) {
|
||||
// if there is no user that means that we are logged off, which means this object can not be used.
|
||||
return
|
||||
}
|
||||
|
||||
user = JSON.parse(user)
|
||||
|
||||
const authId = user.authId
|
||||
|
||||
let sessionToken
|
||||
|
||||
const apolloClient = new Apollo.lib.ApolloClient({
|
||||
networkInterface: Apollo.lib.createNetworkInterface({
|
||||
uri: window.canvasApp.graphQL.masterAppApiUrl,
|
||||
transportBatching: true
|
||||
}),
|
||||
connectToDevTools: true
|
||||
})
|
||||
|
||||
/* Getting the FB that own the Strategies */
|
||||
|
||||
let tradingSystemSimulationClone = ''
|
||||
let clones = window.localStorage.getItem('userClones')
|
||||
if (clones === null || clones === '') {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] loadFromStrategyzer -> no user clones found at local storage. Can not get Strategies without them. ') }
|
||||
return
|
||||
}
|
||||
clones = JSON.parse(clones)
|
||||
for (let i = 0; i < clones.length; i++) {
|
||||
let clone = clones[i]
|
||||
if (clone.botType === 'Indicator') {
|
||||
tradingSystemSimulationClone = clone.botSlug
|
||||
}
|
||||
}
|
||||
|
||||
/* Getting all Strategies */
|
||||
|
||||
const networkInterface = Apollo.lib.createNetworkInterface({
|
||||
uri: window.canvasApp.graphQL.masterAppApiUrl
|
||||
})
|
||||
|
||||
networkInterface.use([{
|
||||
applyMiddleware (req, next) {
|
||||
req.options.headers = {
|
||||
authorization: `Bearer ${accessToken}`
|
||||
}
|
||||
next()
|
||||
}
|
||||
}])
|
||||
|
||||
const getStrategies = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
apolloClient.query({
|
||||
query: GRAPHQL_QUERY_GET_STRATEGIES,
|
||||
variables: { fbSlug: tradingSystemSimulationClone}
|
||||
})
|
||||
.then(response => {
|
||||
window.localStorage.setItem('userStrategies', JSON.stringify(response.data.strategizer_StrategyByFb))
|
||||
thisObject.strategizerData = JSON.parse(JSON.stringify(response.data.strategizer_StrategyByFb))
|
||||
|
||||
resolve({ strategies: response.data.strategizer_StrategyByFb.subStrategies})
|
||||
})
|
||||
.catch(err => {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] loadFromStrategyzer -> ApolloClient error getting user strategies -> err = ' + err.stack) }
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// To avoid race conditions, add asynchronous fetches to array
|
||||
let fetchDataPromises = []
|
||||
|
||||
fetchDataPromises.push(getStrategies())
|
||||
|
||||
// When all asynchronous fetches resolve, authenticate user or throw error.
|
||||
await Promise.all(fetchDataPromises).then(result => {
|
||||
|
||||
}, err => {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] loadFromStrategyzer -> GraphQL Fetch Error -> err = ' + err.stack) }
|
||||
})
|
||||
} catch (err) {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] loadFromStrategyzer -> err = ' + err.stack) }
|
||||
}
|
||||
}
|
||||
|
||||
function deploydTradingSystem () {
|
||||
thisObject.tradingSystem = newTradingSystem()
|
||||
thisObject.tradingSystem.initialize(thisObject.strategizerData)
|
||||
thisObject.isDeployed = true
|
||||
}
|
||||
|
||||
function getContainer (point) {
|
||||
let container
|
||||
|
||||
return undefined
|
||||
}
|
||||
|
||||
function draw () {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,484 +0,0 @@
|
||||
function newTimelineChart () {
|
||||
const MODULE_NAME = 'Timeline Chart'
|
||||
const INFO_LOG = false
|
||||
const INTENSIVE_LOG = false
|
||||
const ERROR_LOG = true
|
||||
const logger = newWebDebugLog()
|
||||
logger.fileName = MODULE_NAME
|
||||
|
||||
let timeLineCoordinateSystem
|
||||
|
||||
let timePeriod = INITIAL_TIME_PERIOD
|
||||
let datetime = NEW_SESSION_INITIAL_DATE
|
||||
|
||||
let thisObject = {
|
||||
setDatetime: setDatetime,
|
||||
container: undefined,
|
||||
drawBackground: drawBackground,
|
||||
draw: draw,
|
||||
getContainer: getContainer,
|
||||
initialize: initialize,
|
||||
finalize: finalize
|
||||
}
|
||||
|
||||
thisObject.container = newContainer()
|
||||
thisObject.container.initialize(MODULE_NAME)
|
||||
thisObject.container.detectMouseOver = true
|
||||
|
||||
let initializationReady = false
|
||||
|
||||
let productsPanel
|
||||
|
||||
/* Background */
|
||||
let logoAssetA
|
||||
let logoAssetB
|
||||
let logoExchange
|
||||
let logoAA
|
||||
let canDrawLogoA = false
|
||||
let canDrawLogoB = false
|
||||
let canDrawLogoExchange = false
|
||||
let canDrawLogoAA = false
|
||||
|
||||
let plotterManager
|
||||
let exchange
|
||||
let market
|
||||
|
||||
let productsPanelHandle
|
||||
let timePeriodScale
|
||||
|
||||
return thisObject
|
||||
|
||||
function finalize () {
|
||||
try {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] finalize -> Entering function.') }
|
||||
|
||||
plotterManager.finalize()
|
||||
} catch (err) {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] finalize -> err = ' + err.stack) }
|
||||
}
|
||||
}
|
||||
|
||||
function initialize (pExchange, pMarket, pTimeLineCoordinateSystem, callBackFunction) {
|
||||
try {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] initialize -> Entering function.') }
|
||||
|
||||
/* We load the logow we will need for the background. */
|
||||
exchange = pExchange
|
||||
market = pMarket
|
||||
timeLineCoordinateSystem = pTimeLineCoordinateSystem
|
||||
|
||||
thisObject.container.eventHandler.listenToEvent('onMouseOver', function (event) {
|
||||
saveUserPosition(thisObject.container, timeLineCoordinateSystem, event)
|
||||
})
|
||||
|
||||
let panelOwner = exchange + ' ' + market.assetB + '/' + market.assetA
|
||||
productsPanelHandle = canvas.panelsSpace.createNewPanel('Products Panel', undefined, panelOwner)
|
||||
let productsPanel = canvas.panelsSpace.getPanel(productsPanelHandle, panelOwner)
|
||||
productsPanel.initialize(exchange, market)
|
||||
|
||||
logoA = new Image()
|
||||
logoB = new Image()
|
||||
logoExchange = new Image()
|
||||
logoAA = new Image()
|
||||
|
||||
logoA.onload = onImageALoaded
|
||||
|
||||
function onImageALoaded () {
|
||||
canDrawLogoA = true
|
||||
}
|
||||
|
||||
logoB.onload = onImageBLoaded
|
||||
|
||||
function onImageBLoaded () {
|
||||
canDrawLogoB = true
|
||||
}
|
||||
|
||||
logoExchange.onload = onImageExchangeLoaded
|
||||
|
||||
function onImageExchangeLoaded () {
|
||||
canDrawLogoExchange = true
|
||||
}
|
||||
|
||||
logoAA.onload = onImageAALoaded
|
||||
|
||||
function onImageAALoaded () {
|
||||
canDrawLogoAA = true
|
||||
}
|
||||
|
||||
logoA.src = window.canvasApp.urlPrefix + 'Images/tether-logo-background.png'
|
||||
logoB.src = window.canvasApp.urlPrefix + 'Images/bitcoin-logo-background.png'
|
||||
logoExchange.src = window.canvasApp.urlPrefix + 'Images/' + exchange + '-logo-background.png'
|
||||
logoAA.src = window.canvasApp.urlPrefix + 'Images/sa-logo-background.png'
|
||||
|
||||
// moveToUserPosition(thisObject.container, timeLineCoordinateSystem, undefined, undefined, undefined, true)
|
||||
timePeriod = INITIAL_TIME_PERIOD
|
||||
datetime = NEW_SESSION_INITIAL_DATE
|
||||
|
||||
/* Event Subscriptions - we need this events to be fired first here and then in active Plotters. */
|
||||
|
||||
viewPort.eventHandler.listenToEvent('Offset Changed', onOffsetChanged)
|
||||
viewPort.eventHandler.listenToEvent('Zoom Changed', onZoomChanged)
|
||||
|
||||
/* Initialize the Plotter Manager */
|
||||
|
||||
plotterManager = newPlottersManager()
|
||||
|
||||
plotterManager.container.connectToParent(thisObject.container, true, true)
|
||||
|
||||
plotterManager.container.frame.position.x = 0
|
||||
plotterManager.container.frame.position.y = 0
|
||||
|
||||
plotterManager.initialize(productsPanel, pExchange, pMarket, onPlotterManagerReady)
|
||||
|
||||
function onPlotterManagerReady (err) {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] initialize -> onPlotterManagerReady -> Entering function.') }
|
||||
|
||||
if (err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> onPlotterManagerReady -> Plotter Manager Initialization Failed. ') }
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> onPlotterManagerReady -> err.message = ' + err.message) }
|
||||
|
||||
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
|
||||
return
|
||||
}
|
||||
|
||||
timePeriodScale = newTimePeriodScale()
|
||||
timePeriodScale.container.connectToParent(thisObject.container, false, false)
|
||||
timePeriodScale.container.eventHandler.listenToEvent('Time Period Changed', function (event) {
|
||||
let currentTimePeriod = timePeriod
|
||||
timePeriod = event.timePeriod
|
||||
if (timePeriod !== currentTimePeriod) {
|
||||
plotterManager.setTimePeriod(timePeriod)
|
||||
}
|
||||
})
|
||||
|
||||
timePeriodScale.initialize(timeLineCoordinateSystem)
|
||||
|
||||
initializationReady = true
|
||||
callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE)
|
||||
return
|
||||
}
|
||||
} catch (err) {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> err = ' + err.stack) }
|
||||
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
|
||||
}
|
||||
}
|
||||
|
||||
function onZoomChanged (event) {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] onZoomChanged -> Entering function.') }
|
||||
|
||||
if (initializationReady === true) {
|
||||
recalculateCurrentDatetime()
|
||||
|
||||
// saveUserPosition(thisObject.container, timeLineCoordinateSystem)
|
||||
}
|
||||
}
|
||||
|
||||
function setDatetime (pDatetime) {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] setDatetime -> Entering function.') }
|
||||
|
||||
/* This function is used when the time is changed through the user interface, but without zooming or panning. */
|
||||
/* No matter if the day changed or not, we need to inform all visible Plotters. */
|
||||
|
||||
if (thisObject.container.frame.isInViewPort()) {
|
||||
plotterManager.setDatetime(pDatetime)
|
||||
plotterManager.positionAtDatetime(pDatetime)
|
||||
}
|
||||
}
|
||||
|
||||
function onOffsetChanged () {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] onOffsetChanged -> Entering function.') }
|
||||
|
||||
if (initializationReady === true) {
|
||||
if (thisObject.container.frame.isInViewPort()) {
|
||||
recalculateCurrentDatetime()
|
||||
// saveUserPosition(thisObject.container, timeLineCoordinateSystem)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function recalculateCurrentDatetime () {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] recalculateCurrentDatetime -> Entering function.') }
|
||||
|
||||
/*
|
||||
|
||||
The view port was moved or the view port zoom level was changed and the center of the screen points to a different datetime that we
|
||||
must calculate.
|
||||
|
||||
*/
|
||||
|
||||
let center = {
|
||||
x: (viewPort.visibleArea.bottomRight.x - viewPort.visibleArea.bottomLeft.x) / 2,
|
||||
y: (viewPort.visibleArea.bottomRight.y - viewPort.visibleArea.topRight.y) / 2
|
||||
}
|
||||
|
||||
center = unTransformThisPoint(center, thisObject.container)
|
||||
center = timeLineCoordinateSystem.unInverseTransform(center, thisObject.container.frame.height)
|
||||
|
||||
let newDate = new Date(0)
|
||||
newDate.setUTCSeconds(center.x / 1000)
|
||||
|
||||
datetime = newDate
|
||||
|
||||
plotterManager.setDatetime(datetime)
|
||||
|
||||
thisObject.container.eventHandler.raiseEvent('Datetime Changed', datetime)
|
||||
}
|
||||
|
||||
function getContainer (point) {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] getContainer -> Entering function.') }
|
||||
|
||||
let container
|
||||
|
||||
container = timePeriodScale.getContainer(point)
|
||||
|
||||
if (container !== undefined) { return container }
|
||||
|
||||
return container
|
||||
}
|
||||
|
||||
function tooTiny () {
|
||||
if (INTENSIVE_LOG === true) { logger.write('[INFO] tooTiny -> Entering function.') }
|
||||
|
||||
if (viewPort.zoomLevel < Math.trunc(-28.25 * 100) / 100) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
function tooSmall () {
|
||||
if (INFO_LOG === true) { logger.write('[INFO] tooSmall -> Entering function.') }
|
||||
|
||||
if (viewPort.zoomLevel < Math.trunc(-27.25 * 100) / 100) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
function drawBackground () {
|
||||
if (INTENSIVE_LOG === true) { logger.write('[INFO] drawBackground -> Entering function.') }
|
||||
|
||||
if (thisObject.container.frame.isInViewPort()) {
|
||||
if (window.CHART_ON_FOCUS === '') {
|
||||
window.CHART_ON_FOCUS = exchange + ' ' + market.assetB + '/' + market.assetA
|
||||
|
||||
drawChartsBackgroundImages()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function draw () {
|
||||
if (INTENSIVE_LOG === true) { logger.write('[INFO] draw -> Entering function.') }
|
||||
|
||||
if (thisObject.container.frame.isInViewPort()) {
|
||||
drawChartsBackground()
|
||||
|
||||
// chartGrid.draw(thisObject.container, timeLineCoordinateSystem)
|
||||
|
||||
timePeriodScale.draw()
|
||||
plotterManager.draw()
|
||||
}
|
||||
}
|
||||
|
||||
function drawChartsBackground () {
|
||||
/* We will paint some transparent background here. */
|
||||
|
||||
let opacity = '0.9'
|
||||
|
||||
let fromPoint = {
|
||||
x: 0,
|
||||
y: 0
|
||||
}
|
||||
|
||||
let toPoint = {
|
||||
x: thisObject.container.frame.width,
|
||||
y: thisObject.container.frame.height
|
||||
}
|
||||
|
||||
fromPoint = transformThisPoint(fromPoint, thisObject.container)
|
||||
toPoint = transformThisPoint(toPoint, thisObject.container)
|
||||
|
||||
browserCanvasContext.beginPath()
|
||||
|
||||
browserCanvasContext.rect(fromPoint.x, fromPoint.y, toPoint.x - fromPoint.x, toPoint.y - fromPoint.y)
|
||||
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + opacity + ')'
|
||||
|
||||
browserCanvasContext.closePath()
|
||||
|
||||
browserCanvasContext.fill()
|
||||
}
|
||||
|
||||
function drawChartsBackgroundImages () {
|
||||
if (INTENSIVE_LOG === true) { logger.write('[INFO] drawChartsBackground -> Entering function.') }
|
||||
|
||||
if (canDrawLogoA === false || canDrawLogoB === false || canDrawLogoExchange === false || canDrawLogoAA === false) { return }
|
||||
|
||||
/* Fist we calculate the corners of the current frame so as not to draw imaages ourside of it */
|
||||
|
||||
let fromPoint = {
|
||||
x: 0,
|
||||
y: 0
|
||||
}
|
||||
|
||||
let toPoint = {
|
||||
x: thisObject.container.frame.width,
|
||||
y: thisObject.container.frame.height
|
||||
}
|
||||
|
||||
fromPoint = transformThisPoint(fromPoint, thisObject.container)
|
||||
toPoint = transformThisPoint(toPoint, thisObject.container)
|
||||
|
||||
/* Second we calculate the points for the images themselves */
|
||||
|
||||
let backgroundLogoPoint1
|
||||
let backgroundLogoPoint2
|
||||
|
||||
let imageHeight = 42
|
||||
let imageWidth = 150
|
||||
|
||||
let MAX_COLUMNS = 16
|
||||
let MAX_ROWS = 7
|
||||
let Y_TOP_MARGIN = 30
|
||||
|
||||
let point1 = {
|
||||
x: viewPort.visibleArea.topLeft.x,
|
||||
y: viewPort.visibleArea.topLeft.y
|
||||
}
|
||||
|
||||
backgroundLogoPoint1 = {
|
||||
x: getDateFromPoint(point1, thisObject.container, timeLineCoordinateSystem).valueOf(),
|
||||
y: getRateFromPoint(point1, thisObject.container, timeLineCoordinateSystem)
|
||||
}
|
||||
|
||||
let point2 = {
|
||||
x: viewPort.visibleArea.topLeft.x + imageWidth * 8,
|
||||
y: viewPort.visibleArea.topLeft.y
|
||||
}
|
||||
|
||||
backgroundLogoPoint2 = {
|
||||
x: getDateFromPoint(point2, thisObject.container, timeLineCoordinateSystem).valueOf(),
|
||||
y: getRateFromPoint(point2, thisObject.container, timeLineCoordinateSystem)
|
||||
}
|
||||
|
||||
let currentCorner = {
|
||||
x: getDateFromPoint(viewPort.visibleArea.topLeft, thisObject.container, timeLineCoordinateSystem).valueOf(),
|
||||
y: getRateFromPoint(viewPort.visibleArea.topLeft, thisObject.container, timeLineCoordinateSystem)
|
||||
}
|
||||
|
||||
currentCorner.x = Math.trunc(currentCorner.x / (backgroundLogoPoint2.x - backgroundLogoPoint1.x)) * (backgroundLogoPoint2.x - backgroundLogoPoint1.x)
|
||||
|
||||
let rowHight = (viewPort.visibleArea.bottomLeft.y - viewPort.visibleArea.topLeft.y) / 4.5
|
||||
|
||||
imagePoint = timeLineCoordinateSystem.transformThisPoint(currentCorner)
|
||||
imagePoint = transformThisPoint(imagePoint, thisObject.container)
|
||||
|
||||
let offSet = 0
|
||||
let imagePosition = {
|
||||
x: 0,
|
||||
y: 0
|
||||
}
|
||||
|
||||
for (let j = 0; j < MAX_ROWS; j++) {
|
||||
if (offSet === -imageWidth * 8) {
|
||||
offSet = -imageWidth * 4 - imageWidth
|
||||
} else {
|
||||
offSet = -imageWidth * 8
|
||||
}
|
||||
|
||||
for (let i = 0; i < MAX_COLUMNS; i = i + 4) {
|
||||
let logo = logoA
|
||||
|
||||
imagePosition.x = imagePoint.x + i * imageWidth * 2 + offSet
|
||||
imagePosition.y = imagePoint.y + j * rowHight + Y_TOP_MARGIN
|
||||
|
||||
if (
|
||||
imagePosition.x > fromPoint.x &&
|
||||
imagePosition.x + imageWidth < toPoint.x &&
|
||||
imagePosition.y > fromPoint.y &&
|
||||
imagePosition.y + imageHeight < toPoint.y
|
||||
) {
|
||||
browserCanvasContext.drawImage(logo, imagePosition.x, imagePosition.y, imageWidth, imageHeight)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
offSet = 0
|
||||
|
||||
for (let j = 0; j < MAX_ROWS; j++) {
|
||||
if (offSet === -imageWidth * 8) {
|
||||
offSet = -imageWidth * 4 - imageWidth
|
||||
} else {
|
||||
offSet = -imageWidth * 8
|
||||
}
|
||||
|
||||
for (let i = 1; i < MAX_COLUMNS; i = i + 4) {
|
||||
let logo = logoB
|
||||
|
||||
imagePosition.x = imagePoint.x + i * imageWidth * 2 + offSet
|
||||
imagePosition.y = imagePoint.y + j * rowHight + Y_TOP_MARGIN
|
||||
|
||||
if (
|
||||
imagePosition.x > fromPoint.x &&
|
||||
imagePosition.x + imageWidth < toPoint.x &&
|
||||
imagePosition.y > fromPoint.y &&
|
||||
imagePosition.y + imageHeight < toPoint.y
|
||||
) {
|
||||
browserCanvasContext.drawImage(logo, imagePosition.x, imagePosition.y, imageWidth, imageHeight)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
offSet = 0
|
||||
|
||||
for (let j = 0; j < MAX_ROWS; j++) {
|
||||
if (offSet === -imageWidth * 8) {
|
||||
offSet = -imageWidth * 4 - imageWidth
|
||||
} else {
|
||||
offSet = -imageWidth * 8
|
||||
}
|
||||
|
||||
for (let i = 2; i < MAX_COLUMNS; i = i + 4) {
|
||||
let logo = logoExchange
|
||||
|
||||
imagePosition.x = imagePoint.x + i * imageWidth * 2 + offSet
|
||||
imagePosition.y = imagePoint.y + j * rowHight + Y_TOP_MARGIN
|
||||
|
||||
if (
|
||||
imagePosition.x > fromPoint.x &&
|
||||
imagePosition.x + imageWidth < toPoint.x &&
|
||||
imagePosition.y > fromPoint.y &&
|
||||
imagePosition.y + imageHeight < toPoint.y
|
||||
) {
|
||||
browserCanvasContext.drawImage(logo, imagePosition.x, imagePosition.y, imageWidth, imageHeight)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
offSet = 0
|
||||
|
||||
for (let j = 0; j < MAX_ROWS; j++) {
|
||||
if (offSet === -imageWidth * 8) {
|
||||
offSet = -imageWidth * 4 - imageWidth
|
||||
} else {
|
||||
offSet = -imageWidth * 8
|
||||
}
|
||||
|
||||
for (let i = 3; i < MAX_COLUMNS; i = i + 4) {
|
||||
let logo = logoAA
|
||||
|
||||
imagePosition.x = imagePoint.x + i * imageWidth * 2 + offSet
|
||||
imagePosition.y = imagePoint.y + j * rowHight + Y_TOP_MARGIN
|
||||
|
||||
if (
|
||||
imagePosition.x > fromPoint.x &&
|
||||
imagePosition.x + imageWidth < toPoint.x &&
|
||||
imagePosition.y > fromPoint.y &&
|
||||
imagePosition.y + imageHeight < toPoint.y
|
||||
) {
|
||||
browserCanvasContext.drawImage(logo, imagePosition.x, imagePosition.y, imageWidth, imageHeight)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -70,7 +70,7 @@ function newCurrentEvent () {
|
||||
thisObject.container = container
|
||||
|
||||
thisObject.container.frame.width = 150
|
||||
thisObject.container.frame.height = BOTTOM_SPACE_HEIGHT
|
||||
thisObject.container.frame.height = COCKPIT_SPACE_HEIGHT
|
||||
|
||||
resize()
|
||||
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ function newEndUser () {
|
||||
thisObject.container = container
|
||||
|
||||
thisObject.container.frame.width = 200
|
||||
thisObject.container.frame.height = BOTTOM_SPACE_HEIGHT
|
||||
thisObject.container.frame.height = COCKPIT_SPACE_HEIGHT
|
||||
|
||||
container.frame.position.x = viewPort.visibleArea.topRight.x - thisObject.container.frame.width * 5
|
||||
container.frame.position.y = viewPort.visibleArea.bottomLeft.y + BREAKPOINT_HEIGHT
|
||||
|
||||
+6
-5
@@ -5,6 +5,7 @@ function newLogin () {
|
||||
const INTENSIVE_LOG = false
|
||||
const ERROR_LOG = true
|
||||
const logger = newWebDebugLog()
|
||||
logger.fileName = MODULE_NAME
|
||||
|
||||
let thisObject = {
|
||||
container: undefined,
|
||||
@@ -18,7 +19,7 @@ function newLogin () {
|
||||
thisObject.container = container
|
||||
|
||||
thisObject.container.frame.width = 200
|
||||
thisObject.container.frame.height = BOTTOM_SPACE_HEIGHT
|
||||
thisObject.container.frame.height = COCKPIT_SPACE_HEIGHT
|
||||
|
||||
container.frame.position.x = viewPort.visibleArea.topRight.x - thisObject.container.frame.width * 1
|
||||
container.frame.position.y = viewPort.visibleArea.bottomLeft.y + BREAKPOINT_HEIGHT
|
||||
@@ -100,7 +101,7 @@ function newLogin () {
|
||||
resolve({ user: response.data.users_UserByAuthId})
|
||||
})
|
||||
.catch(error => {
|
||||
console.log('apolloClient error getting user query', error)
|
||||
console.log('apolloClient error getting user query', error.graphQLErrors, error.stack)
|
||||
reject(error)
|
||||
})
|
||||
})
|
||||
@@ -170,7 +171,7 @@ function newLogin () {
|
||||
resolve({ teams: response.data.teams_TeamsByOwner})
|
||||
})
|
||||
.catch(error => {
|
||||
console.log('apolloClient error getting user teams', error)
|
||||
console.log('apolloClient error getting user teams', error.graphQLErrors, error.stack)
|
||||
reject(error)
|
||||
})
|
||||
})
|
||||
@@ -233,7 +234,7 @@ function newLogin () {
|
||||
resolve({ currentEvents: response.data.events_Events})
|
||||
})
|
||||
.catch(error => {
|
||||
console.log('apolloClient error getting current events', error)
|
||||
console.log('apolloClient error getting current events', error.graphQLErrors, error.stack)
|
||||
reject(error)
|
||||
})
|
||||
})
|
||||
@@ -320,7 +321,7 @@ function newLogin () {
|
||||
resolve({ clones: response.data.operations_Clones})
|
||||
})
|
||||
.catch(error => {
|
||||
console.log('apolloClient error getting user clones', error)
|
||||
console.log('apolloClient error getting user clones', error.graphQLErrors, error.stack)
|
||||
reject(error)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -153,3 +153,23 @@ function removeTime (datetime) {
|
||||
|
||||
return dateOnly
|
||||
}
|
||||
|
||||
function printLabel (labelToPrint, x, y, opacity, fontSize) {
|
||||
let labelPoint
|
||||
|
||||
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
|
||||
|
||||
let label = '' + labelToPrint
|
||||
|
||||
let xOffset = label.length / 2 * fontSize * FONT_ASPECT_RATIO
|
||||
|
||||
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.DARK + ', ' + opacity + ')'
|
||||
browserCanvasContext.fillText(label, x, y)
|
||||
}
|
||||
|
||||
function newUniqueId () {
|
||||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
||||
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8)
|
||||
return v.toString(16)
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
function roundedCornersBackground (params) {
|
||||
borderPoint1 = {
|
||||
x: params.cornerRadius,
|
||||
y: params.cornerRadius
|
||||
}
|
||||
|
||||
borderPoint2 = {
|
||||
x: params.container.frame.width - params.cornerRadius,
|
||||
y: params.cornerRadius
|
||||
}
|
||||
|
||||
borderPoint3 = {
|
||||
x: params.container.frame.width - params.cornerRadius,
|
||||
y: params.container.frame.height - params.cornerRadius
|
||||
}
|
||||
|
||||
borderPoint4 = {
|
||||
x: params.cornerRadius,
|
||||
y: params.container.frame.height - params.cornerRadius
|
||||
}
|
||||
|
||||
/* Now the transformations. */
|
||||
|
||||
if (params.coordinateSystem !== undefined) { // For instance Candles would use this
|
||||
borderPoint1 = params.coordinateSystem.transformThisPoint(borderPoint1)
|
||||
borderPoint2 = params.coordinateSystem.transformThisPoint(borderPoint2)
|
||||
borderPoint3 = params.coordinateSystem.transformThisPoint(borderPoint3)
|
||||
borderPoint4 = params.coordinateSystem.transformThisPoint(borderPoint4)
|
||||
} else {
|
||||
if (params.outsideViewPort === true) { // If the element is not affected by zoom
|
||||
borderPoint1 = transformThisPoint(borderPoint1, params.container)
|
||||
borderPoint2 = transformThisPoint(borderPoint2, params.container)
|
||||
borderPoint3 = transformThisPoint(borderPoint3, params.container)
|
||||
borderPoint4 = transformThisPoint(borderPoint4, params.container)
|
||||
} else { // For instance Panels use this
|
||||
borderPoint1 = params.container.frame.frameThisPoint(borderPoint1)
|
||||
borderPoint2 = params.container.frame.frameThisPoint(borderPoint2)
|
||||
borderPoint3 = params.container.frame.frameThisPoint(borderPoint3)
|
||||
borderPoint4 = params.container.frame.frameThisPoint(borderPoint4)
|
||||
}
|
||||
}
|
||||
|
||||
if (params.fitFunction !== undefined) {
|
||||
borderPoint1 = params.fitFunction(borderPoint1)
|
||||
borderPoint2 = params.fitFunction(borderPoint2)
|
||||
borderPoint3 = params.fitFunction(borderPoint3)
|
||||
borderPoint4 = params.fitFunction(borderPoint4)
|
||||
}
|
||||
|
||||
browserCanvasContext.setLineDash([0, 0])
|
||||
|
||||
/* Shadow */
|
||||
|
||||
if (params.castShadow === true) {
|
||||
let SHADOW_OFFSET = 2
|
||||
|
||||
browserCanvasContext.beginPath()
|
||||
|
||||
browserCanvasContext.arc(borderPoint1.x + SHADOW_OFFSET, borderPoint1.y + SHADOW_OFFSET, params.cornerRadius, 1.0 * Math.PI, 1.5 * Math.PI)
|
||||
browserCanvasContext.lineTo(borderPoint2.x + SHADOW_OFFSET, borderPoint2.y - params.cornerRadius + SHADOW_OFFSET)
|
||||
browserCanvasContext.arc(borderPoint2.x + SHADOW_OFFSET, borderPoint2.y + SHADOW_OFFSET, params.cornerRadius, 1.5 * Math.PI, 2.0 * Math.PI)
|
||||
browserCanvasContext.lineTo(borderPoint3.x + params.cornerRadius + SHADOW_OFFSET, borderPoint3.y + SHADOW_OFFSET)
|
||||
browserCanvasContext.arc(borderPoint3.x + SHADOW_OFFSET, borderPoint3.y + SHADOW_OFFSET, params.cornerRadius, 0 * Math.PI, 0.5 * Math.PI)
|
||||
browserCanvasContext.lineTo(borderPoint4.x + SHADOW_OFFSET, borderPoint4.y + params.cornerRadius + SHADOW_OFFSET)
|
||||
browserCanvasContext.arc(borderPoint4.x + SHADOW_OFFSET, borderPoint4.y + SHADOW_OFFSET, params.cornerRadius, 0.5 * Math.PI, 1.0 * Math.PI)
|
||||
browserCanvasContext.lineTo(borderPoint1.x - params.cornerRadius + SHADOW_OFFSET, borderPoint1.y + SHADOW_OFFSET)
|
||||
|
||||
browserCanvasContext.closePath()
|
||||
|
||||
browserCanvasContext.lineWidth = 10
|
||||
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.BLACK + ', ' + 0.01 + ')'
|
||||
browserCanvasContext.stroke()
|
||||
|
||||
browserCanvasContext.lineWidth = 5
|
||||
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.BLACK + ', ' + 0.01 + ')'
|
||||
browserCanvasContext.stroke()
|
||||
|
||||
browserCanvasContext.lineWidth = 1
|
||||
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.BLACK + ', ' + 0.15 + ')'
|
||||
browserCanvasContext.stroke()
|
||||
}
|
||||
|
||||
/* Background */
|
||||
|
||||
browserCanvasContext.beginPath()
|
||||
|
||||
browserCanvasContext.arc(borderPoint1.x, borderPoint1.y, params.cornerRadius, 1.0 * Math.PI, 1.5 * Math.PI)
|
||||
browserCanvasContext.lineTo(borderPoint2.x, borderPoint2.y - params.cornerRadius)
|
||||
browserCanvasContext.arc(borderPoint2.x, borderPoint2.y, params.cornerRadius, 1.5 * Math.PI, 2.0 * Math.PI)
|
||||
browserCanvasContext.lineTo(borderPoint3.x + params.cornerRadius, borderPoint3.y)
|
||||
browserCanvasContext.arc(borderPoint3.x, borderPoint3.y, params.cornerRadius, 0 * Math.PI, 0.5 * Math.PI)
|
||||
browserCanvasContext.lineTo(borderPoint4.x, borderPoint4.y + params.cornerRadius)
|
||||
browserCanvasContext.arc(borderPoint4.x, borderPoint4.y, params.cornerRadius, 0.5 * Math.PI, 1.0 * Math.PI)
|
||||
browserCanvasContext.lineTo(borderPoint1.x - params.cornerRadius, borderPoint1.y)
|
||||
|
||||
browserCanvasContext.closePath()
|
||||
|
||||
browserCanvasContext.fillStyle = 'rgba(' + params.backgroundColor + ', ' + params.opacity + ')'
|
||||
|
||||
browserCanvasContext.fill()
|
||||
|
||||
browserCanvasContext.lineWidth = params.lineWidth
|
||||
browserCanvasContext.strokeStyle = 'rgba(' + params.borderColor + ', ' + params.opacity + ')'
|
||||
browserCanvasContext.stroke()
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
function newVolumeBar () {
|
||||
var volumeBar = {
|
||||
amountBuy: 0,
|
||||
amountSell: 0,
|
||||
begin: undefined,
|
||||
end: undefined
|
||||
}
|
||||
|
||||
return volumeBar
|
||||
}
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
function newWebDebugLog () {
|
||||
let thisObject = {
|
||||
write: write,
|
||||
fileName: undefined
|
||||
fileName: 'undefined'
|
||||
}
|
||||
|
||||
return thisObject
|
||||
|
||||
Reference in new issue
Block a user