Merge pull request #106 from AAMasters/develop

Pre-Release
This commit is contained in:
Luis Fernando Molina authored and GitHub committed 2020-02-08 21:59:07 +01:00
commit 55b027ffe2
67 files changed
+5472 -16565

No files matched your search

+4 -11
View File
@@ -57,21 +57,14 @@ function newAnimation () {
function animationLoop () {
try {
if (window.canvasApp.visible === true) {
/* We set the canvas to its normal width and height */
/* We set the canvas to its normal width and height */
browserCanvas.width = window.innerWidth
browserCanvas.height = window.innerHeight - CURRENT_TOP_MARGIN
/* First thing is to clear the actual canvas */
clearBrowserCanvas()
/* Let reset the current chart that is on focus */
window.CHART_ON_FOCUS = ''
/* We loop through the callback functions collections and execute them all. */
/* First thing is to clear the actual canvas */
// clearBrowserCanvas()
/* We loop through the callback functions collections and execute them all. */
let performanceMap = new Map()
let totalTimeConsumed = 0
let totalElements = 0
+61 -47
View File
@@ -120,18 +120,16 @@ function newCanvas () {
animation.addCallBackFunction('System Event Handler Physics', systemEventHandler.physics)
/* Spcaces Physics */
animation.addCallBackFunction('CockpitSpace Physics', thisObject.cockpitSpace.physics)
animation.addCallBackFunction('Floating Space Physics', thisObject.floatingSpace.physics)
animation.addCallBackFunction('Chart Space Physics', thisObject.chartSpace.physics)
animation.addCallBackFunction('CockpitSpace Physics', thisObject.cockpitSpace.physics)
animation.addCallBackFunction('Strategy Space Physics', thisObject.designerSpace.physics)
animation.addCallBackFunction('Panels Space Physics', thisObject.panelsSpace.physics)
/* Spcaces Drawing */
animation.addCallBackFunction('Floating Space Draw', thisObject.floatingSpace.draw)
animation.addCallBackFunction('Chart Space Background', thisObject.chartSpace.drawBackground)
animation.addCallBackFunction('Chart Space Draw', thisObject.chartSpace.draw)
animation.addCallBackFunction('Panels Space', thisObject.panelsSpace.draw)
animation.addCallBackFunction('ViewPort Animate', viewPort.animate)
animation.addCallBackFunction('CockpitSpace Draw', thisObject.cockpitSpace.draw)
animation.addCallBackFunction('Designer Space Draw', thisObject.designerSpace.draw)
animation.addCallBackFunction('Top Space Draw', thisObject.topSpace.draw)
@@ -145,9 +143,7 @@ function newCanvas () {
function initializeBrowserCanvas () {
try {
browserCanvasContext = browserCanvas.getContext('2d')
browserCanvasContext.font = 'Saira'
viewPort.initialize()
browserCanvasContext.font = 'Saira Condensed'
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] initializeBrowserCanvas -> err = ' + err.stack) }
}
@@ -155,11 +151,12 @@ function newCanvas () {
function addCanvasEvents () {
try {
canvas.eventHandler.listenToEvent('Browser Resized', browserResized)
/* Keyboard events */
window.addEventListener('keydown', onKeyDown, true)
/* Mouse Events */
browserCanvas.addEventListener('mousedown', onMouseDown, false)
browserCanvas.addEventListener('mouseup', onMouseUp, false)
browserCanvas.addEventListener('mousemove', onMouseMove, false)
@@ -172,7 +169,6 @@ function newCanvas () {
} else browserCanvas.attachEvent('onmousewheel', onMouseWheel)// IE 6/7/8
/* Dragging Files Over the Canvas */
browserCanvas.addEventListener('dragenter', onDragEnter, false)
browserCanvas.addEventListener('dragleave', onDragLeave, false)
browserCanvas.addEventListener('dragover', onDragOver, false)
@@ -187,6 +183,17 @@ function newCanvas () {
}
}
function browserResized () {
try {
browserCanvas = document.getElementById('canvas')
browserCanvas.width = window.innerWidth
browserCanvas.height = window.innerHeight - CURRENT_TOP_MARGIN
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] browserResized -> err = ' + err.stack) }
}
}
function onKeyDown (event) {
let nodeOnFocus = canvas.designerSpace.workspace.getNodeThatIsOnFocus()
if (nodeOnFocus !== undefined) {
@@ -501,7 +508,7 @@ function newCanvas () {
container = thisObject.chartSpace.getContainer(point)
if (container !== undefined) {
if (container.isDraggeable === true) {
if (container.isDraggeable === true && event.button === 2) {
containerBeingDragged = container
containerDragStarted = true
containerBeingDragged.eventHandler.raiseEvent('onDragStarted', point)
@@ -624,8 +631,10 @@ function newCanvas () {
y: event.pageY - CURRENT_TOP_MARGIN
}
viewPort.mousePosition.x = point.x
viewPort.mousePosition.y = point.y
if (canvas.chartSpace.viewport !== undefined) {
canvas.chartSpace.viewport.mousePosition.x = point.x
canvas.chartSpace.viewport.mousePosition.y = point.y
}
if (containerDragStarted === true || floatingObjectDragStarted === true || viewPortBeingDragged === true) {
if (floatingObjectDragStarted === true) {
@@ -655,9 +664,8 @@ function newCanvas () {
dragVector.upY = point.y
checkDrag(event)
} else {
onMouseOver(event)
}
onMouseOver(event)
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] onMouseMove -> err = ' + err.stack) }
}
@@ -665,8 +673,16 @@ function newCanvas () {
function onMouseOver (event) {
try {
/* Then we check who is the current object underneeth the mounse. */
if (containerDragStarted === true) {
let point = {
x: event.pageX,
y: event.pageY - CURRENT_TOP_MARGIN
}
containerBeingDragged.eventHandler.raiseEvent('onMouseOver', point)
return
}
/* Then we check who is the current object underneeth the mounse. */
let point = {
x: event.pageX,
y: event.pageY - CURRENT_TOP_MARGIN
@@ -674,8 +690,7 @@ function newCanvas () {
let container
/* We check if the mouse is over an element of the Strategy Space / */
/* We check if the mouse is over an element of the Strategy Space / */
if (thisObject.designerSpace !== undefined) {
container = thisObject.designerSpace.getContainer(point)
@@ -685,8 +700,7 @@ function newCanvas () {
}
}
/* We check if the mouse is over an element of the Top Space / */
/* We check if the mouse is over an element of the Top Space / */
if (thisObject.topSpace !== undefined) {
container = thisObject.topSpace.getContainer(point)
@@ -696,8 +710,7 @@ function newCanvas () {
}
}
/* We check if the mouse is over an element of the CockpitSpace / */
/* We check if the mouse is over an element of the CockpitSpace / */
if (thisObject.cockpitSpace !== undefined) {
container = thisObject.cockpitSpace.getContainer(point)
@@ -707,8 +720,7 @@ function newCanvas () {
}
}
/* We check if the mouse is over a panel/ */
/* We check if the mouse is over a panel/ */
if (thisObject.panelsSpace !== undefined) {
container = thisObject.panelsSpace.getContainer(point)
@@ -718,8 +730,7 @@ function newCanvas () {
}
}
/* If it is not, then we check if it is over any of the existing containers at the Chart Space. */
/* If it is not, then we check if it is over any of the existing containers at the Chart Space. */
if (thisObject.chartSpace !== undefined) {
container = thisObject.chartSpace.getContainer(point, GET_CONTAINER_PURPOSE.MOUSE_OVER)
@@ -745,7 +756,6 @@ function newCanvas () {
lastContainerMouseOver.eventHandler.raiseEvent('onMouseNotOver', point)
}
}
container.eventHandler.raiseEvent('onMouseOver', point)
lastContainerMouseOver = container
}
@@ -758,7 +768,7 @@ function newCanvas () {
try {
// cross-browser wheel delta
var event = window.event || event // old IE support
let delta = Math.max(-1, Math.min(1, event.wheelDelta || -event.detail))
event.delta = Math.max(-1, Math.min(1, event.wheelDelta || -event.detail))
/* We try first with panels. */
@@ -794,7 +804,7 @@ function newCanvas () {
}
if (container !== undefined) {
viewPort.applyZoom(delta)
canvas.chartSpace.viewport.onMouseWheel(event)
return false
}
@@ -850,32 +860,36 @@ function newCanvas () {
thisObject.eventHandler.raiseEvent('Dragging', undefined)
if (containerDragStarted || viewPortBeingDragged) {
/* The parameters received have been captured with zoom applied. We must remove the zoom in order to correctly modify the displacement. */
let downCopy = {
x: dragVector.downX,
y: dragVector.downY
}
let downCopyNoTransf
downCopyNoTransf = viewPort.unzoomThisPoint(downCopy)
// downCopyNoTransf = containerBeingDragged.zoom.unzoomThisPoint(downCopyNoTransf);
let upCopy = {
x: dragVector.upX,
y: dragVector.upY
}
let upCopyNoTranf
upCopyNoTranf = viewPort.unzoomThisPoint(upCopy)
let displaceVector = {
x: dragVector.upX - dragVector.downX,
y: dragVector.upY - dragVector.downY
}
if (containerBeingDragged !== undefined && containerBeingDragged.insideViewport === true) {
let downCopy = {
x: dragVector.downX,
y: dragVector.downY
}
let downNoZoom
downNoZoom = canvas.chartSpace.viewport.unTransformThisPoint(downCopy)
let upCopy = {
x: dragVector.upX,
y: dragVector.upY
}
let upNoZoom
upNoZoom = canvas.chartSpace.viewport.unTransformThisPoint(upCopy)
displaceVector = {
x: upNoZoom.x - downNoZoom.x,
y: upNoZoom.y - downNoZoom.y
}
}
if (viewPortBeingDragged) {
viewPort.displace(displaceVector)
canvas.chartSpace.viewport.displace(displaceVector)
}
if (containerBeingDragged !== undefined) {
+33 -37
View File
@@ -1,48 +1,48 @@
function getSideDays (timePeriod) {
function getSideDays (timeFrame) {
let daysOnSides
if (timePeriod < _1_HOUR_IN_MILISECONDS) {
if (timeFrame < _1_HOUR_IN_MILISECONDS) {
daysOnSides = 1
}
if (timePeriod === _1_HOUR_IN_MILISECONDS) {
if (timeFrame === _1_HOUR_IN_MILISECONDS) {
daysOnSides = 9
}
if (timePeriod === _2_HOURS_IN_MILISECONDS) {
if (timeFrame === _2_HOURS_IN_MILISECONDS) {
daysOnSides = 10
}
if (timePeriod === _3_HOURS_IN_MILISECONDS) {
if (timeFrame === _3_HOURS_IN_MILISECONDS) {
daysOnSides = 12
}
if (timePeriod === _4_HOURS_IN_MILISECONDS) {
if (timeFrame === _4_HOURS_IN_MILISECONDS) {
daysOnSides = 20
}
if (timePeriod === _6_HOURS_IN_MILISECONDS) {
if (timeFrame === _6_HOURS_IN_MILISECONDS) {
daysOnSides = 35
}
if (timePeriod === _8_HOURS_IN_MILISECONDS) {
if (timeFrame === _8_HOURS_IN_MILISECONDS) {
daysOnSides = 44
}
if (timePeriod === _12_HOURS_IN_MILISECONDS) {
if (timeFrame === _12_HOURS_IN_MILISECONDS) {
daysOnSides = 56
}
if (timePeriod === ONE_DAY_IN_MILISECONDS) {
if (timeFrame === ONE_DAY_IN_MILISECONDS) {
daysOnSides = 154
}
return daysOnSides
}
function getCondenseFactor (timePeriod) {
switch (timePeriod) {
function getCondenseFactor (timeFrame) {
switch (timeFrame) {
case _1_MINUTE_IN_MILISECONDS: return 1
case _5_MINUTES_IN_MILISECONDS: return 5
case _10_MINUTES_IN_MILISECONDS: return 10
@@ -51,8 +51,8 @@ function getCondenseFactor (timePeriod) {
}
}
function getTransparenceFactor (timePeriod) {
switch (timePeriod) {
function getTransparenceFactor (timeFrame) {
switch (timeFrame) {
case _1_MINUTE_IN_MILISECONDS: return '0.12'
case _5_MINUTES_IN_MILISECONDS: return '0.10'
case _10_MINUTES_IN_MILISECONDS: return '0.08'
@@ -62,82 +62,78 @@ function getTransparenceFactor (timePeriod) {
}
function recalculatePeriod (zoomLevel) {
// console.log(" recalculatePeriod > " + zoomLevel);
if (zoomLevel > 200) {
// console.log('NEW ZOOM LEVEL', zoomLevel)
if (zoomLevel > 400) {
return _1_MINUTE_IN_MILISECONDS
}
if (zoomLevel > 120) {
if (zoomLevel > 360) {
return _2_MINUTES_IN_MILISECONDS
}
if (zoomLevel > 80) {
if (zoomLevel > 330) {
return _3_MINUTES_IN_MILISECONDS
}
if (zoomLevel > 60) {
if (zoomLevel > 300) {
return _4_MINUTES_IN_MILISECONDS
}
if (zoomLevel > 15) {
if (zoomLevel > 270) {
return _5_MINUTES_IN_MILISECONDS
}
if (zoomLevel > -7) {
if (zoomLevel > 250) {
return _10_MINUTES_IN_MILISECONDS
}
if (zoomLevel > -10) {
if (zoomLevel > 230) {
return _15_MINUTES_IN_MILISECONDS
}
if (zoomLevel > -13) {
if (zoomLevel > 210) {
return _20_MINUTES_IN_MILISECONDS
}
if (zoomLevel > -15) {
if (zoomLevel > 190) {
return _30_MINUTES_IN_MILISECONDS
}
if (zoomLevel > -16) {
if (zoomLevel > 170) {
return _40_MINUTES_IN_MILISECONDS
}
if (zoomLevel > -17) {
if (zoomLevel > 150) {
return _45_MINUTES_IN_MILISECONDS
}
if (zoomLevel > -18) {
if (zoomLevel > 130) {
return _1_HOUR_IN_MILISECONDS
}
if (zoomLevel > -24) {
if (zoomLevel > 110) {
return _2_HOURS_IN_MILISECONDS
}
if (zoomLevel > -25) {
if (zoomLevel > 80) {
return _3_HOURS_IN_MILISECONDS
}
if (zoomLevel > -27) {
if (zoomLevel > 50) {
return _4_HOURS_IN_MILISECONDS
}
if (zoomLevel > -27.5) {
if (zoomLevel > 35) {
return _6_HOURS_IN_MILISECONDS
}
if (zoomLevel > -27.75) {
if (zoomLevel > 20) {
return _8_HOURS_IN_MILISECONDS
}
if (zoomLevel > -28) {
if (zoomLevel > 10) {
return _12_HOURS_IN_MILISECONDS
}
if (zoomLevel <= -28) {
return ONE_DAY_IN_MILISECONDS
}
return ONE_DAY_IN_MILISECONDS
}
@@ -7,65 +7,75 @@ The scale on the Y axis depends on the data that wants to be plotted. Usually we
*/
function newTimeLineCoordinateSystem () {
function newCoordinateSystem () {
let thisObject = {
min: undefined,
max: undefined,
maxHeight: undefined,
maxWidth: undefined,
scale: undefined,
eventHandler: undefined,
recalculateScale: recalculateScale,
transformThisPoint: transformThisPoint,
transformThisPoint2: transformThisPoint2,
unInverseTransform: unInverseTransform,
inverseTransformUncappedY: inverseTransformUncappedY,
initializeX: initializeX,
initializeY: initializeY,
initialize: initialize
initialize: initialize,
finalize: finalize
}
var min = {
thisObject.min = {
x: 0,
y: 0
}
thisObject.max = {
x: 0,
y: 0
}
thisObject.scale = {
x: 0,
y: 0
}
var max = {
x: 0,
y: 0
}
var scale = {
x: 0,
y: 0
}
thisObject.min = min
thisObject.max = max
thisObject.scale = scale
let maxHeight
thisObject.eventHandler = newEventHandler()
thisObject.eventHandler.name = 'Coordinate System'
return thisObject
function initialize (minValue, maxValue, maxWidth, pMaxHeight) {
/* Defines the min and max value of rate that we are going to transport to the available screen at the center position. */
function finalize () {
thisObject.eventHandler.finalize()
thisObject.eventHandler = undefined
}
function initialize (minValue, maxValue, pMaxWidth, pMaxHeight) {
/* Defines the min and max value of rate that we are going to transport to the available screen at the center position. */
thisObject.min.x = minValue.x // * 0.999; // 0.1% less
thisObject.max.x = maxValue.x // * 1.001; // 0.1% more
thisObject.min.y = minValue.y // * 0.999; // 0.1% less
thisObject.max.y = maxValue.y // * 1.001; // 0.1% more
/* Defines the initial Zoom level at center position. */
thisObject.maxWidth = pMaxWidth
thisObject.maxHeight = pMaxHeight
thisObject.scale.x = maxWidth / (thisObject.max.x - thisObject.min.x)
thisObject.scale.y = pMaxHeight / (thisObject.max.y - thisObject.min.y)
recalculateScale()
}
maxHeight = pMaxHeight
function recalculateScale () {
/* Defines the initial Zoom level at center position. */
thisObject.scale.x = thisObject.maxWidth / (thisObject.max.x - thisObject.min.x)
thisObject.scale.y = thisObject.maxHeight / (thisObject.max.y - thisObject.min.y)
thisObject.eventHandler.raiseEvent('Scale Changed')
}
function initializeX (minValue, maxValue, maxWidth) {
thisObject.min.x = minValue.x // * 0.999; // 0.1% less
thisObject.max.x = maxValue.x // * 1.001; // 0.1% more
thisObject.scale.x = maxWidth / (thisObject.max.x - thisObject.min.x)
thisObject.scale.x = thisObject.maxWidth / (thisObject.max.x - thisObject.min.x)
}
function initializeY (minValue, maxValue, pMaxHeight) {
@@ -74,7 +84,7 @@ function newTimeLineCoordinateSystem () {
thisObject.scale.y = pMaxHeight / (thisObject.max.y - thisObject.min.y)
maxHeight = pMaxHeight
thisObject.maxHeight = pMaxHeight
}
function transformThisPoint (point) {
@@ -92,8 +102,8 @@ function newTimeLineCoordinateSystem () {
*/
point = {
x: (point.x - this.min.x) * this.scale.x,
y: maxHeight - (point.y - this.min.y) * this.scale.y
x: (point.x - thisObject.min.x) * thisObject.scale.x,
y: thisObject.maxHeight - (point.y - thisObject.min.y) * thisObject.scale.y
}
return point
@@ -101,8 +111,8 @@ function newTimeLineCoordinateSystem () {
function transformThisPoint2 (point) {
point = {
x: (point.x - this.min.x) * this.scale.x,
y: (maxHeight - point.y - this.min.y) * this.scale.y
x: (point.x - thisObject.min.x) * thisObject.scale.x,
y: (thisObject.maxHeight - point.y - thisObject.min.y) * thisObject.scale.y
}
return point
@@ -110,8 +120,8 @@ function newTimeLineCoordinateSystem () {
function unInverseTransform (point, inverseY) {
point = {
x: (point.x / this.scale.x) + this.min.x,
y: (inverseY - point.y) / this.scale.y + this.min.y
x: (point.x / thisObject.scale.x) + thisObject.min.x,
y: (inverseY - point.y) / thisObject.scale.y + thisObject.min.y
}
return point
@@ -119,11 +129,10 @@ function newTimeLineCoordinateSystem () {
function inverseTransformUncappedY (point, inverseY) {
point = {
x: (point.x - this.min.x) * this.scale.x,
y: (inverseY - point.y) * this.scale.y
x: (point.x - thisObject.min.x) * thisObject.scale.x,
y: (inverseY - point.y) * thisObject.scale.y
}
return point
}
}
+182 -224
View File
@@ -4,28 +4,29 @@ function newPlottersManager () {
const logger = newWebDebugLog()
logger.fileName = MODULE_NAME
let productPlotters = []
let timePeriod = INITIAL_TIME_PERIOD
let timeFrame = INITIAL_TIME_PERIOD
let datetime = NEW_SESSION_INITIAL_DATE
let thisObject = {
fitFunction: undefined,
container: undefined,
payload: undefined,
connectors: [],
setDatetime: setDatetime,
setTimePeriod: setTimePeriod,
positionAtDatetime: positionAtDatetime,
setTimeFrame: setTimeFrame,
setCoordinateSystem: setCoordinateSystem,
draw: draw,
getContainer: getContainer,
initialize: initialize,
finalize: finalize
}
let initializationReady = false
thisObject.connectors = []
let productsPanel
let exchange
let market
let initializationReady = false
let layersPanel
let onLayerStatusChangedEventSuscriptionId
let coordinateSystem
setupContainer()
return thisObject
@@ -36,304 +37,261 @@ function newPlottersManager () {
}
function finalize () {
for (let i = 0; i < productPlotters.length; i++) {
layersPanel.container.eventHandler.stopListening(onLayerStatusChangedEventSuscriptionId)
layersPanel = undefined
for (let i = 0; i < thisObject.connectors.length; i++) {
let connector = thisObject.connectors[i]
/* Then the panels. */
for (let j = 0; j < productPlotters[i].panels.length; j++) {
canvas.panelsSpace.destroyPanel(productPlotters[i].panels[j])
productPlotters[i].panels[j] = undefined
for (let j = 0; j < connector.panels.length; j++) {
canvas.panelsSpace.destroyPanel(connector.panels[j])
connector.panels[j] = undefined
}
productPlotters[i].panels = undefined
connector.panels = undefined
/* Finalize the plotters */
if (productPlotters[i].plotter.finalize !== undefined) {
productPlotters[i].plotter.finalize()
if (connector.plotter.finalize !== undefined) {
connector.plotter.container.eventHandler.stopListening(connector.plotter.onRecordChangeEventsSubscriptionId)
connector.plotter.finalize()
}
productPlotters[i].plotter = undefined
connector.plotter = undefined
/* Finally the Storage Objects */
productPlotters[i].storage.finalize()
productPlotters[i].storage = undefined
finalizeStorage(connector.storage)
connector.storage = undefined
productPlotters[i] = undefined
connector = undefined
}
productPlotters = []
productsPanel = undefined
thisObject.connectors = []
coordinateSystem = undefined
thisObject.container.finalize()
thisObject.container = undefined
setupContainer()
thisObject.payload = undefined
}
function initialize (pProductsPanel, pExchange, pMarket, callBackFunction) {
try {
/* Remember the Products Panel */
productsPanel = pProductsPanel
exchange = pExchange
market = pMarket
/* Listen to the event of change of status */
productsPanel.container.eventHandler.listenToEvent('Product Card Status Changed', onProductCardStatusChanged)
/* Lets get all the cards that needs to be loaded. */
let initializationCounter = 0
let loadingProductCards = productsPanel.getLoadingProductCards()
let okCounter = 0
let failCounter = 0
if (loadingProductCards.length === 0) {
callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE)
return
}
for (let i = 0; i < loadingProductCards.length; i++) {
/* For each one, we will initialize the associated plotter. */
initializeProductPlotter(loadingProductCards[i], onProductPlotterInitialized)
function onProductPlotterInitialized (err) {
initializationCounter++
switch (err.result) {
case GLOBAL.DEFAULT_OK_RESPONSE.result: {
okCounter++
break
}
case GLOBAL.DEFAULT_FAIL_RESPONSE.result: {
failCounter++
break
}
default: {
failCounter++
break
}
}
if (initializationCounter === loadingProductCards.length) {
// This was the last one.
/* If less than 50% of plotters are initialized then we return FAIL. */
if (okCounter >= 1) {
initializationReady = true
callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE)
} else {
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
}
}
}
}
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> err = ' + err.stack) }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
}
function finalizeStorage (storage) {
storage.eventHandler.stopListening(storage.onMarketFileLoadedLayerEventsSubscriptionId)
storage.eventHandler.stopListening(storage.onDailyFileLoadedLayerEventsSubscriptionId)
storage.eventHandler.stopListening(storage.onSingleFileLoadedLayerEventsSubscriptionId)
storage.eventHandler.stopListening(storage.onFileSequenceLoadedLayerEventsSubscriptionId)
storage.eventHandler.stopListening(storage.onDailyFileLoadedPlotterEventsSubscriptionId)
storage.finalize()
}
function initializeProductPlotter (pProductCard, callBack) {
function initialize (pLayersPanel) {
/* Remember the Layers Panel */
layersPanel = pLayersPanel
/* Listen to the event of change of status */
onLayerStatusChangedEventSuscriptionId = layersPanel.container.eventHandler.listenToEvent('Layer Status Changed', onLayerStatusChanged)
}
function initializePlotter (layer) {
try {
/* Before Initializing a Plotter, we need the Storage it will use, loaded with the files it will initially need. */
let objName = pProductCard.devTeam.codeName + '-' + pProductCard.bot.codeName + '-' + pProductCard.product.codeName
let storage = newProductStorage(objName)
/*
/* Before Initializing a Plotter, we need the Storage it will use, loaded with the files it will initially need. */
let storage = newProductStorage(layer.payload.node.id)
Before Initializing the Storage, we will put the Product Card to listen to the events the storage will raise every time a file is loaded,
so that the UI can somehow show this. There are different types of events.
/*
Before Initializing the Storage, we will put the Layer to listen to the events the storage will raise every time a file is loaded,
so that the UI can somehow show this. There are different types of events.
*/
for (let i = 0; i < layer.definition.referenceParent.referenceParent.datasets.length; i++) {
let dataset = layer.definition.referenceParent.referenceParent.datasets[i]
*/
for (let i = 0; i < pProductCard.product.dataSets.length; i++) {
let thisSet = pProductCard.product.dataSets[i]
switch (thisSet.type) {
switch (dataset.code.type) {
case 'Market Files': {
storage.eventHandler.listenToEvent('Market File Loaded', pProductCard.onMarketFileLoaded)
storage.onMarketFileLoadedLayerEventsSubscriptionId = storage.eventHandler.listenToEvent('Market File Loaded', layer.onMarketFileLoaded)
}
break
case 'Daily Files': {
storage.eventHandler.listenToEvent('Daily File Loaded', pProductCard.onDailyFileLoaded)
storage.onDailyFileLoadedLayerEventsSubscriptionId = storage.eventHandler.listenToEvent('Daily File Loaded', layer.onDailyFileLoaded)
}
break
case 'Single File': {
storage.eventHandler.listenToEvent('Single File Loaded', pProductCard.onSingleFileLoaded)
storage.onSingleFileLoadedLayerEventsSubscriptionId = storage.eventHandler.listenToEvent('Single File Loaded', layer.onSingleFileLoaded)
}
break
case 'File Sequence': {
storage.eventHandler.listenToEvent('File Sequence Loaded', pProductCard.onFileSequenceLoaded)
storage.onFileSequenceLoadedLayerEventsSubscriptionId = storage.eventHandler.listenToEvent('File Sequence Loaded', layer.onFileSequenceLoaded)
}
break
default: {
if (ERROR_LOG === true) {
logger.write('[ERROR] initializePlotter -> Dataset Type Incorrect or Undefined -> dataset.type = ' + dataset.type)
}
return
}
}
}
storage.initialize(pProductCard.devTeam, pProductCard.bot, pProductCard.session, pProductCard.product, exchange, market, datetime, timePeriod, onProductStorageInitialized)
let baseAsset = layer.definition.referenceParent.parentNode.referenceParent.baseAsset.referenceParent.code.codeName
let quotedAsset = layer.definition.referenceParent.parentNode.referenceParent.quotedAsset.referenceParent.code.codeName
let market = {
baseAsset: baseAsset,
quotedAsset: quotedAsset
}
let product = layer.definition.referenceParent.referenceParent
let bot = layer.definition.referenceParent.referenceParent.parentNode
let dataMine = layer.definition.referenceParent.referenceParent.parentNode.parentNode
let exchange = layer.definition.referenceParent.parentNode.referenceParent.parentNode.parentNode
let plotterModule = layer.definition.referenceParent.referenceParent.referenceParent
let session
if (layer.definition.referenceParent.parentNode.parentNode !== undefined) {
if (layer.definition.referenceParent.parentNode.parentNode.type === 'Session Reference') {
if (layer.definition.referenceParent.parentNode.parentNode.referenceParent !== undefined) {
session = layer.definition.referenceParent.parentNode.parentNode.referenceParent
}
}
}
storage.initialize(
dataMine,
bot,
session,
product,
exchange,
market,
datetime,
timeFrame,
onProductStorageInitialized
)
function onProductStorageInitialized (err) {
try {
switch (err.result) {
case GLOBAL.DEFAULT_OK_RESPONSE.result: {
break
if (err.result === GLOBAL.DEFAULT_OK_RESPONSE.result) {
/* Now we have all the initial data loaded and ready to be delivered to the new instance of the plotter. */
let plotter
if (plotterModule.code.isLegacy !== true) {
plotter = newPlotter()
} else {
plotter = getNewPlotter(dataMine.code.codeName, plotterModule.parentNode.code.codeName, plotterModule.code.codeName)
}
case GLOBAL.DEFAULT_FAIL_RESPONSE.result: {
callBack(GLOBAL.DEFAULT_FAIL_RESPONSE)
return
}
default: {
callBack(GLOBAL.DEFAULT_FAIL_RESPONSE)
return
}
}
/* Now we have all the initial data loaded and ready to be delivered to the new instance of the plotter. */
let plotter
let productDefinition
if (pProductCard.product.plotter.legacy === false) {
plotter = newPlotter()
plotter.container.connectToParent(thisObject.container, true, true, false, true, true, true, false, false, true)
plotter.container.frame.position.x = thisObject.container.frame.width / 2 - plotter.container.frame.width / 2
plotter.container.frame.position.y = thisObject.container.frame.height / 2 - plotter.container.frame.height / 2
plotter.fitFunction = thisObject.fitFunction
plotter.initialize(storage, datetime, timeFrame, coordinateSystem, onPlotterInizialized, product)
/* We take a snapwhot of the current product definition to be used by the plotter. */
let functionLibraryProtocolNode = newProtocolNode()
productDefinition = functionLibraryProtocolNode.getProtocolNode(pProductCard.product.node, false, true, true, false, false, true)
} else {
plotter = getNewPlotter(pProductCard.product.plotter.devTeam, pProductCard.product.plotter.codeName, pProductCard.product.plotter.moduleName)
}
plotter.container.connectToParent(thisObject.container, true, true, false, true, true, true)
plotter.container.frame.position.x = thisObject.container.frame.width / 2 - plotter.container.frame.width / 2
plotter.container.frame.position.y = thisObject.container.frame.height / 2 - plotter.container.frame.height / 2
plotter.fitFunction = thisObject.fitFunction
plotter.initialize(storage, exchange, market, datetime, timePeriod, onPlotterInizialized, productDefinition)
function onPlotterInizialized () {
try {
let productPlotter = {
productCard: pProductCard,
plotter: plotter,
storage: storage,
profile: undefined,
notes: undefined
}
/* Let the Plotter listen to the event of Cursor Files loaded, so that it can react recalculating if needed. */
storage.eventHandler.listenToEvent('Daily File Loaded', plotter.onDailyFileLoaded)
/* Lets load now this plotter panels. */
productPlotter.panels = []
/* Here is where we instantiate the legacy panels */
for (let i = 0; i < pProductCard.product.plotter.module.panels.length; i++) {
let panelConfig = pProductCard.product.plotter.module.panels[i]
let parameters = {
devTeam: pProductCard.product.plotter.devTeam,
plotterCodeName: pProductCard.product.plotter.codeName,
moduleCodeName: pProductCard.product.plotter.moduleName,
panelCodeName: panelConfig.codeName
function onPlotterInizialized () {
try {
let connector = {
layer: layer,
plotter: plotter,
storage: storage
}
let panelOwner = exchange + ' ' + market.assetB + '/' + market.assetA
let plotterPanelHandle = canvas.panelsSpace.createNewPanel('Plotter Panel', parameters, panelOwner, pProductCard.session)
let plotterPanel = canvas.panelsSpace.getPanel(plotterPanelHandle, panelOwner)
/* Connect Panel to the Plotter via an Event. */
if (panelConfig.event !== undefined) {
productPlotter.plotter.container.eventHandler.listenToEvent(panelConfig.event, plotterPanel.onEventRaised)
}
productPlotter.panels.push(plotterPanelHandle)
}
/* Let the Plotter listen to the event of Cursor Files loaded, so that it can react recalculating if needed. */
plotter.onDailyFileLoadedPlotterEventsSubscriptionId = storage.eventHandler.listenToEvent('Daily File Loaded', plotter.onDailyFileLoaded)
/* Lets load now this plotter panels. */
connector.panels = []
/* Here we instantiate the UI Defined Panels. */
if (productDefinition !== undefined) {
for (let i = 0; i < productDefinition.referenceParent.panels.length; i++) {
let panel = productDefinition.referenceParent.panels[i]
if (product !== undefined) {
for (let i = 0; i < plotterModule.panels.length; i++) {
let panel = plotterModule.panels[i]
let parameters = {
devTeam: pProductCard.product.plotter.devTeam,
plotterCodeName: pProductCard.product.plotter.codeName,
moduleCodeName: pProductCard.product.plotter.moduleName,
panelCodeName: panel.id
let parameters = {
dataMine: dataMine.code.codeName,
plotterCodeName: plotterModule.parentNode.code.codeName,
moduleCodeName: plotterModule.code.codeName,
panelNode: panel
}
let owner = thisObject.payload.node.payload.parentNode.id // Panels are owned by the time machine.
let plotterPanelHandle = canvas.panelsSpace.createNewPanel('Plotter Panel', parameters, owner, layer.session)
let plotterPanel = canvas.panelsSpace.getPanel(plotterPanelHandle)
/* Connect Panel to the Plotter via an Event. */
connector.plotter.onRecordChangeEventsSubscriptionId = connector.plotter.container.eventHandler.listenToEvent('Current Record Changed', plotterPanel.onRecordChange)
connector.panels.push(plotterPanelHandle)
}
let panelOwner = exchange + ' ' + market.assetB + '/' + market.assetA
let plotterPanelHandle = canvas.panelsSpace.createNewPanel('Plotter Panel', parameters, panelOwner, pProductCard.session, panel)
let plotterPanel = canvas.panelsSpace.getPanel(plotterPanelHandle, panelOwner)
/* Connect Panel to the Plotter via an Event. */
productPlotter.plotter.container.eventHandler.listenToEvent('Current Record Changed', plotterPanel.onRecordChange)
productPlotter.panels.push(plotterPanelHandle)
connector.layer.panels = connector.panels
}
}
productPlotters.push(productPlotter)
callBack(GLOBAL.DEFAULT_OK_RESPONSE)
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] initializeProductPlotter -> onProductStorageInitialized -> onPlotterInizialized -> err = ' + err.stack) }
callBack(GLOBAL.DEFAULT_FAIL_RESPONSE)
thisObject.connectors.push(connector)
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] initializePlotter -> onProductStorageInitialized -> onPlotterInizialized -> err = ' + err.stack) }
}
}
}
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] initializeProductPlotter -> onProductStorageInitialized -> err = ' + err.stack) }
callBack(GLOBAL.DEFAULT_FAIL_RESPONSE)
if (ERROR_LOG === true) { logger.write('[ERROR] initializePlotter -> onProductStorageInitialized -> err = ' + err.stack) }
}
}
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] initializeProductPlotter -> err = ' + err.stack) }
callBack(GLOBAL.DEFAULT_FAIL_RESPONSE)
if (ERROR_LOG === true) { logger.write('[ERROR] initializePlotter -> err = ' + err.stack) }
}
}
function onProductCardStatusChanged (pProductCard) {
if (pProductCard.status === PRODUCT_CARD_STATUS.LOADING) {
function onLayerStatusChanged (layer) {
if (layer.status === LAYER_STATUS.LOADING) {
/* Lets see if we can find the Plotter of this card on our Active Plotters list, other wise we will initialize it */
let found = false
for (let i = 0; i < productPlotters.length; i++) {
if (productPlotters[i].productCard.code === pProductCard.code) {
for (let i = 0; i < thisObject.connectors.length; i++) {
let connector = thisObject.connectors[i]
if (connector.layer.payload.node.id === layer.payload.node.id) {
found = true
}
}
if (found === false) {
initializeProductPlotter(pProductCard, onProductPlotterInitialized)
initializePlotter(layer, onProductPlotterInitialized)
function onProductPlotterInitialized (err) {
/* There is no policy yet of what to do if this fails. */
}
}
}
if (pProductCard.status === PRODUCT_CARD_STATUS.OFF) {
if (layer.status === LAYER_STATUS.OFF) {
/* If the plotter of this card is not on our Active Plotters list, then we remove it. */
for (let i = 0; i < productPlotters.length; i++) {
if (productPlotters[i].productCard.code === pProductCard.code) {
for (let i = 0; i < thisObject.connectors.length; i++) {
let connector = thisObject.connectors[i]
if (connector.layer.payload.node.id === layer.payload.node.id) {
/* Then the panels. */
for (let j = 0; j < productPlotters[i].panels.length; j++) {
canvas.panelsSpace.destroyPanel(productPlotters[i].panels[j])
for (let j = 0; j < connector.panels.length; j++) {
canvas.panelsSpace.destroyPanel(connector.panels[j])
}
/* Finally the Storage Objects */
if (productPlotters[i].plotter.finalize !== undefined) {
productPlotters[i].plotter.container.finalize()
productPlotters[i].plotter.finalize()
if (connector.plotter.finalize !== undefined) {
connector.plotter.container.eventHandler.stopListening(connector.plotter.onRecordChangeEventsSubscriptionId)
connector.plotter.container.finalize()
connector.plotter.finalize()
}
productPlotters[i].storage.finalize()
productPlotters.splice(i, 1) // Delete item from array.
finalizeStorage(connector.storage)
thisObject.connectors.splice(i, 1) // Delete item from array.
return // We already found the product woth changes and processed it.
}
}
}
}
function setTimePeriod (pTimePeriod) {
timePeriod = pTimePeriod
if (initializationReady === true) {
for (let i = 0; i < productPlotters.length; i++) {
let productPlotter = productPlotters[i]
productPlotter.productCard.setTimePeriod(timePeriod)
productPlotter.storage.setTimePeriod(timePeriod)
productPlotter.plotter.setTimePeriod(timePeriod)
}
function setTimeFrame (pTimeFrame) {
timeFrame = pTimeFrame
for (let i = 0; i < thisObject.connectors.length; i++) {
let connector = thisObject.connectors[i]
connector.layer.setTimeFrame(timeFrame)
connector.storage.setTimeFrame(timeFrame)
connector.plotter.setTimeFrame(timeFrame)
}
}
function setDatetime (pDatetime) {
datetime = pDatetime
for (let i = 0; i < productPlotters.length; i++) {
let productPlotter = productPlotters[i]
productPlotter.productCard.setDatetime(pDatetime)
productPlotter.storage.setDatetime(pDatetime)
productPlotter.plotter.setDatetime(pDatetime)
for (let i = 0; i < thisObject.connectors.length; i++) {
let connector = thisObject.connectors[i]
connector.layer.setDatetime(pDatetime)
connector.storage.setDatetime(pDatetime)
connector.plotter.setDatetime(pDatetime)
}
}
function positionAtDatetime (pDatetime) {
for (let i = 0; i < productPlotters.length; i++) {
let productPlotter = productPlotters[i]
if (productPlotter.plotter.positionAtDatetime !== undefined) {
productPlotter.plotter.positionAtDatetime(pDatetime)
}
function setCoordinateSystem (pCoordinateSystem) {
coordinateSystem = pCoordinateSystem
for (let i = 0; i < thisObject.connectors.length; i++) {
let connector = thisObject.connectors[i]
connector.plotter.setCoordinateSystem(coordinateSystem)
}
}
@@ -341,11 +299,11 @@ function newPlottersManager () {
}
function draw () {
if (productPlotters === undefined) { return } // We need to wait
if (thisObject.connectors === undefined) { return } // We need to wait
/* First the Product Plotters. */
for (let i = 0; i < productPlotters.length; i++) {
let productPlotter = productPlotters[i]
productPlotter.plotter.draw()
for (let i = 0; i < thisObject.connectors.length; i++) {
let connector = thisObject.connectors[thisObject.connectors.length - i - 1]
connector.plotter.draw()
}
}
}
+455 -246
View File
@@ -4,8 +4,8 @@ Markets are a function of time. When watching them, end users must be positioned
to position themselves at any time they like.
In the future, it will be usefull to explore markets and compare them at different times simultaneously. Anticipating that future this module exists.
All the charts that depand on a datetime are children of this object Time Machine. In the future we will allow users to have more than one Time Machine,
each one with it own charts, and each one positioned at an especific point in titme.
All the timelineCharts that depand on a datetime are children of this object Time Machine. In the future we will allow users to have more than one Time Machine,
each one with it own timelineCharts, and each one positioned at an especific point in titme.
*/
@@ -14,25 +14,25 @@ function newTimeMachine () {
const logger = newWebDebugLog()
logger.fileName = MODULE_NAME
let timeFrame = INITIAL_TIME_PERIOD
let thisObject = {
container: undefined,
timeScale: undefined,
rateScale: undefined,
fitFunction: undefined,
charts: [],
payload: undefined,
timelineCharts: [],
fitFunction: fitFunction,
physics: physics,
drawBackground: drawBackground,
draw: draw,
drawBackground: drawBackground,
drawForeground: drawForeground,
getContainer: getContainer, // returns the inner most container that holds the point received by parameter.
initialize: initialize,
finalize: finalize
}
let controlPanelHandle // We need this to destroy the Panel when this object is itself destroyed or no longer needs it...
// ... also to request a reference to the object for the cases we need it.
const SEPARATION_BETWEEN_TIMELINE_CHARTS = 1.5
let timeLineCoordinateSystem = newTimeLineCoordinateSystem()
let timeMachineCoordinateSystem = newCoordinateSystem()
let mouse = {
position: {
@@ -41,188 +41,235 @@ function newTimeMachine () {
}
}
let drawScales = false
let syncWithDesignerLoop = 0
let timelineChartsMap = new Map()
let onViewportPositionChangedEventSuscriptionId
let onViewportZoomChangedEventSuscriptionId
let onMouseOverEventSuscriptionId
let onMouseNotOverEventSuscriptionId
let timeScaleValueEventSuscriptionId
let timeScaleMouseOverEventSuscriptionId
let rateScaleValueEventSuscriptionId
let rateScaleMouseOverEventSuscriptionId
let timeFrameScaleEventSuscriptionId
let timeFrameScaleMouseOverEventSuscriptionId
setupContainer()
return thisObject
function setupContainer () {
thisObject.container = newContainer()
thisObject.container.initialize(MODULE_NAME)
thisObject.container.isDraggeable = false
thisObject.container.fitFunction = thisObject.fitFunction
thisObject.container.isDraggeable = true
thisObject.container.insideViewport = true
thisObject.container.detectMouseOver = true
thisObject.container.frame.width = TIME_MACHINE_WIDTH
thisObject.container.frame.height = TIME_MACHINE_HEIGHT
thisObject.container.frame.position.x = browserCanvas.width / 2 - TIME_MACHINE_WIDTH / 2
thisObject.container.frame.position.y = browserCanvas.height / 2 - TIME_MACHINE_HEIGHT / 2
}
function finalize () {
for (let i = 0; i < thisObject.charts.length; i++) {
let chart = thisObject.charts[i]
chart.finalize()
}
thisObject.charts = []
canvas.chartSpace.viewport.eventHandler.stopListening(onViewportPositionChangedEventSuscriptionId)
canvas.chartSpace.viewport.eventHandler.stopListening(onViewportZoomChangedEventSuscriptionId)
if (thisObject.timeScale !== undefined) {
thisObject.timeScale.finalize()
thisObject.timeScale = undefined
finalizeTimeScale()
}
if (thisObject.rateScale !== undefined) {
thisObject.rateScale.finalize()
thisObject.rateScale = undefined
finalizeRateScale()
}
thisObject.fitFunction = undefined
if (thisObject.timeFrameScale !== undefined) {
finalizeTimeFrameScale()
}
thisObject.container.eventHandler.stopListening(onMouseOverEventSuscriptionId)
thisObject.container.eventHandler.stopListening(onMouseNotOverEventSuscriptionId)
for (let i = 0; i < thisObject.timelineCharts.length; i++) {
let timelineChart = thisObject.timelineCharts[i]
timelineChart.container.eventHandler.stopListening(timelineChart.onChildrenMouseOverEventSuscriptionId)
timelineChart.finalize()
}
thisObject.timelineCharts = undefined
thisObject.fitFunction = undefined
thisObject.container.finalize()
thisObject.container = undefined
setupContainer()
thisObject.payload = undefined
mouse = undefined
timelineChartsMap = undefined
timeMachineCoordinateSystem.finalize()
timeMachineCoordinateSystem = undefined
}
function finalizeTimeScale () {
if (thisObject.timeScale === undefined) { return }
thisObject.timeScale.container.eventHandler.stopListening(timeScaleValueEventSuscriptionId)
thisObject.timeScale.container.eventHandler.stopListening(timeScaleMouseOverEventSuscriptionId)
thisObject.timeScale.finalize()
thisObject.timeScale = undefined
}
function finalizeRateScale () {
if (thisObject.rateScale === undefined) { return }
thisObject.rateScale.container.eventHandler.stopListening(rateScaleValueEventSuscriptionId)
thisObject.rateScale.container.eventHandler.stopListening(rateScaleMouseOverEventSuscriptionId)
thisObject.rateScale.finalize()
thisObject.rateScale = undefined
}
function finalizeTimeFrameScale () {
if (thisObject.timeFrameScale === undefined) { return }
thisObject.timeFrameScale.container.eventHandler.stopListening(timeFrameScaleEventSuscriptionId)
thisObject.timeFrameScale.container.eventHandler.stopListening(timeFrameScaleMouseOverEventSuscriptionId)
thisObject.timeFrameScale.finalize()
thisObject.timeFrameScale = undefined
}
function initialize (callBackFunction) {
/* Each Time Machine has a Control Panel. */
timeFrame = INITIAL_TIME_PERIOD
loadFrame(thisObject.payload, thisObject.container.frame)
let panelOwner = 'Global'
controlPanelHandle = canvas.panelsSpace.createNewPanel('Time Control Panel', undefined, panelOwner)
let controlPanel = canvas.panelsSpace.getPanel(controlPanelHandle, panelOwner)
recalculateCoordinateSystem()
recalculateCurrentDatetime()
recalculateScale()
onMouseOverEventSuscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver)
onMouseNotOverEventSuscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver)
/* 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. */
onViewportPositionChangedEventSuscriptionId = canvas.chartSpace.viewport.eventHandler.listenToEvent('Position Changed', onViewportPositionChanged)
onViewportZoomChangedEventSuscriptionId = canvas.chartSpace.viewport.eventHandler.listenToEvent('Zoom Changed', onViewportZoomChanged)
let position = 0 // This defines the position of each chart respect to each other.
callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE)
}
let timelineChart = newTimelineChart()
function onMouseOver (event) {
drawScales = true
timelineChart.container.connectToParent(thisObject.container, true, true, false, true, true, true)
timelineChart.container.frame.height = thisObject.container.frame.height
mouse.position.x = event.x
mouse.position.y = event.y
timelineChart.container.frame.position.x = thisObject.container.frame.width / 2 - timelineChart.container.frame.width / 2
timelineChart.container.frame.position.y = timelineChart.container.frame.height * SEPARATION_BETWEEN_TIMELINE_CHARTS * position
position++
timelineChart.initialize(DEFAULT_EXCHANGE, DEFAULT_MARKET, timeLineCoordinateSystem, onDefaultInitialized)
function onDefaultInitialized (err) {
if (err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) {
callBackFunction(err)
return
}
thisObject.charts.push(timelineChart)
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. */
thisObject.timeScale = newTimeScale()
thisObject.timeScale.fitFunction = thisObject.fitFunction
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)
})
thisObject.timeScale.initialize()
thisObject.rateScale = newRateScale()
thisObject.rateScale.fitFunction = thisObject.fitFunction
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)
})
thisObject.rateScale.initialize()
thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver)
initializeTheRest()
if (thisObject.timeScale !== undefined) {
thisObject.timeScale.onMouseOverSomeTimeMachineContainer(event)
}
function onMouseOver (event) {
thisObject.timeScale.visible = true
thisObject.rateScale.visible = true
mouse.position.x = event.x
mouse.position.y = event.y
if (thisObject.rateScale !== undefined) {
thisObject.rateScale.onMouseOverSomeTimeMachineContainer(event)
}
if (thisObject.timeFrameScale !== undefined) {
thisObject.timeFrameScale.onMouseOverSomeTimeMachineContainer(event)
}
}
function initializeTheRest () {
let leftToInitialize = SUPPORTED_EXCHANGES.length * SUPPORTED_MARKETS.length - 1 // The default exchange and market was already initialized.
let alreadyInitialized = 0
function onMouseNotOver (event) {
drawScales = false
if (alreadyInitialized === leftToInitialize) {
callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE)
return
if (thisObject.timeScale !== undefined) {
thisObject.timeScale.visible = false
}
if (thisObject.rateScale !== undefined) {
thisObject.rateScale.visible = false
}
if (thisObject.timeFrameScale !== undefined) {
thisObject.timeFrameScale.visible = false
}
}
function initializeTimeScale () {
thisObject.timeScale = newTimeScale()
thisObject.timeScale.fitFunction = thisObject.fitFunction
thisObject.timeScale.payload = thisObject.payload.node.timeScale.payload
timeScaleValueEventSuscriptionId = thisObject.timeScale.container.eventHandler.listenToEvent('Time Scale Value Changed', timeScaleValueChanged)
timeScaleMouseOverEventSuscriptionId = thisObject.timeScale.container.eventHandler.listenToEvent('onMouseOverScale', timeScaleMouseOver)
thisObject.timeScale.initialize(timeMachineCoordinateSystem, thisObject.container)
function timeScaleValueChanged (event) {
if (event.isUserAction === true) {
let currentDate = getDateFromPoint(event.mousePosition, thisObject.container, timeMachineCoordinateSystem)
let currentRate = getRateFromPoint(event.mousePosition, thisObject.container, timeMachineCoordinateSystem)
thisObject.container.frame.width = TIME_MACHINE_WIDTH + TIME_MACHINE_WIDTH * event.scale
recalculateCoordinateSystem()
moveToUserPosition(thisObject.container, currentDate, currentRate, timeMachineCoordinateSystem, false, true, event.mousePosition)
} else {
thisObject.container.frame.width = TIME_MACHINE_WIDTH + TIME_MACHINE_WIDTH * event.scale
recalculateCoordinateSystem()
}
thisObject.container.eventHandler.raiseEvent('Dimmensions Changed', event)
}
function timeScaleMouseOver (event) {
thisObject.container.eventHandler.raiseEvent('onMouseOver', event)
}
}
for (let i = 0; i < SUPPORTED_EXCHANGES.length; i++) {
for (let j = 0; j < SUPPORTED_MARKETS.length; j++) {
let exchange = SUPPORTED_EXCHANGES[i]
let market = SUPPORTED_MARKETS[j]
function initializeRateScale () {
thisObject.rateScale = newRateScale()
thisObject.rateScale.fitFunction = thisObject.fitFunction
thisObject.rateScale.payload = thisObject.payload.node.rateScale.payload
if (
exchange === DEFAULT_EXCHANGE &&
market.assetA === DEFAULT_MARKET.assetA &&
market.assetB === DEFAULT_MARKET.assetB
) { continue }
rateScaleValueEventSuscriptionId = thisObject.rateScale.container.eventHandler.listenToEvent('Rate Scale Value Changed', rateScaleValueChanged)
rateScaleMouseOverEventSuscriptionId = thisObject.rateScale.container.eventHandler.listenToEvent('onMouseOverScale', rateScaleMouseOver)
thisObject.rateScale.initialize(timeMachineCoordinateSystem, thisObject.container, thisObject.container)
initializeTimelineChart(exchange, market)
}
function rateScaleValueChanged (event) {
if (event.isUserAction === true) {
let currentDate = getDateFromPoint(event.mousePosition, thisObject.container, timeMachineCoordinateSystem)
let currentRate = getRateFromPoint(event.mousePosition, thisObject.container, timeMachineCoordinateSystem)
thisObject.container.frame.height = TIME_MACHINE_HEIGHT + TIME_MACHINE_HEIGHT * event.scale
recalculateCoordinateSystem()
moveToUserPosition(thisObject.container, currentDate, currentRate, timeMachineCoordinateSystem, true, false, event.mousePosition)
} else {
thisObject.container.frame.height = TIME_MACHINE_HEIGHT + TIME_MACHINE_HEIGHT * event.scale
recalculateCoordinateSystem()
}
thisObject.container.eventHandler.raiseEvent('Dimmensions Changed', event)
thisObject.container.eventHandler.raiseEvent('Upstream Rate Scale Value Changed', event)
}
function rateScaleMouseOver (event) {
thisObject.container.eventHandler.raiseEvent('onMouseOver', event)
}
}
function initializeTimelineChart (exchange, market) {
let timelineChart = newTimelineChart()
function initializeTimeFrameScale () {
thisObject.timeFrameScale = newTimeFrameScale()
thisObject.timeFrameScale.fitFunction = thisObject.fitFunction
thisObject.timeFrameScale.payload = thisObject.payload.node.timeFrameScale.payload
timelineChart.container.connectToParent(thisObject.container, true, true, false, true, true, true)
timeFrameScaleEventSuscriptionId = thisObject.timeFrameScale.container.eventHandler.listenToEvent('Time Frame Value Changed', timeFrameScaleValueChanged)
timeFrameScaleMouseOverEventSuscriptionId = thisObject.timeFrameScale.container.eventHandler.listenToEvent('onMouseOverScale', timeFrameScaleMouseOver)
thisObject.timeFrameScale.initialize(thisObject.container)
timelineChart.container.frame.height = thisObject.container.frame.height
timelineChart.container.frame.position.x = thisObject.container.frame.width / 2 - timelineChart.container.frame.width / 2
timelineChart.container.frame.position.y = timelineChart.container.frame.height * SEPARATION_BETWEEN_TIMELINE_CHARTS * position
position++
timelineChart.initialize(exchange, market, timeLineCoordinateSystem, finalSteps)
function finalSteps () {
thisObject.charts.push(timelineChart)
controlPanel.container.eventHandler.listenToEvent('Datetime Changed', timelineChart.setDatetime, undefined)
timelineChart.container.eventHandler.listenToEvent('Datetime Changed', controlPanel.setDatetime)
alreadyInitialized++
if (alreadyInitialized === leftToInitialize) {
callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE)
function timeFrameScaleValueChanged (event) {
let currentTimeFrame = timeFrame
timeFrame = event.timeFrame
if (timeFrame !== currentTimeFrame) {
for (let i = 0; i < thisObject.timelineCharts.length; i++) {
let timelineChart = thisObject.timelineCharts[i]
timelineChart.upstreamTimeFrame = timeFrame
if (timelineChart.timeFrameScale === undefined) {
timelineChart.setTimeFrame(timeFrame)
}
}
}
}
function timeFrameScaleMouseOver (event) {
thisObject.container.eventHandler.raiseEvent('onMouseOver', event)
}
}
function getContainer (point, purpose) {
let container
if (thisObject.timeScale !== undefined) {
container = thisObject.timeScale.getContainer(point)
if (container !== undefined) {
if (container.isForThisPurpose(purpose)) {
return container
}
}
}
if (thisObject.rateScale !== undefined) {
if (thisObject.rateScale !== undefined && thisObject.rateScale.isVisible === true) {
container = thisObject.rateScale.getContainer(point)
if (container !== undefined) {
if (container.isForThisPurpose(purpose)) {
@@ -231,8 +278,26 @@ function newTimeMachine () {
}
}
for (let i = 0; i < this.charts.length; i++) {
container = this.charts[i].getContainer(point)
if (thisObject.timeScale !== undefined && thisObject.timeScale.isVisible === true) {
container = thisObject.timeScale.getContainer(point)
if (container !== undefined) {
if (container.isForThisPurpose(purpose)) {
return container
}
}
}
if (thisObject.timeFrameScale !== undefined && thisObject.timeFrameScale.isVisible === true) {
container = thisObject.timeFrameScale.getContainer(point)
if (container !== undefined) {
if (container.isForThisPurpose(purpose)) {
return container
}
}
}
for (let i = 0; i < thisObject.timelineCharts.length; i++) {
container = thisObject.timelineCharts[i].getContainer(point, purpose)
if (container !== undefined) {
if (container.isForThisPurpose(purpose)) {
if (thisObject.container.frame.isThisPointHere(point) === true) {
@@ -244,143 +309,277 @@ function newTimeMachine () {
if (thisObject.container.frame.isThisPointHere(point) === true) {
return thisObject.container
} else {
if (purpose === GET_CONTAINER_PURPOSE.MOUSE_OVER) {
thisObject.container.eventHandler.raiseEvent('onMouseNotOver')
if (thisObject.timeScale !== undefined) {
thisObject.timeScale.visible = false
}
if (thisObject.rateScale !== undefined) {
thisObject.rateScale.visible = false
}
}
return
}
}
function onViewportZoomChanged (event) {
if (thisObject.container.frame.isInViewPort()) {
recalculateCurrentDatetime()
}
}
function onViewportPositionChanged () {
if (thisObject.container.frame.isInViewPort()) {
recalculateCurrentDatetime()
}
}
function recalculateCurrentDatetime () {
/*
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: (canvas.chartSpace.viewport.visibleArea.bottomRight.x - canvas.chartSpace.viewport.visibleArea.bottomLeft.x) / 2,
y: (canvas.chartSpace.viewport.visibleArea.bottomRight.y - canvas.chartSpace.viewport.visibleArea.topRight.y) / 2
}
center = unTransformThisPoint(center, thisObject.container)
center = timeMachineCoordinateSystem.unInverseTransform(center, thisObject.container.frame.height)
datetime = new Date(center.x)
for (let i = 0; i < thisObject.timelineCharts.length; i++) {
let timelineChart = thisObject.timelineCharts[i]
timelineChart.setDatetime(datetime)
}
}
function fitFunction (point, fullVisible, margin, topMargin, bottomMargin) {
/* We prevent a point to be out of the container AND out of the Chart Space in general */
let returnPoint = {
x: point.x,
y: point.y
}
let upCorner = {
x: 0,
y: 0
}
let bottonCorner = {
x: thisObject.container.frame.width,
y: thisObject.container.frame.height
}
upCorner = transformThisPoint(upCorner, thisObject.container)
bottonCorner = transformThisPoint(bottonCorner, thisObject.container)
/* Checking against the container limits. */
if (margin === undefined) { margin = 0 }
if (topMargin === undefined) { topMargin = 0 }
if (bottomMargin === undefined) { bottomMargin = 0 }
if (returnPoint.x - margin < upCorner.x) { returnPoint.x = upCorner.x + margin }
if (returnPoint.x + margin > bottonCorner.x) { returnPoint.x = bottonCorner.x - margin }
if (returnPoint.y - margin - topMargin < upCorner.y) { returnPoint.y = upCorner.y + margin + topMargin }
if (returnPoint.y + margin + bottomMargin > bottonCorner.y) { returnPoint.y = bottonCorner.y - margin - bottomMargin }
returnPoint = canvas.chartSpace.fitFunction(returnPoint, fullVisible)
return returnPoint
}
function physics () {
thisObjectPhysics()
childrenPhysics()
saveFrame(thisObject.payload, thisObject.container.frame)
if (thisObject.container.frame.isInViewPort()) {
childrenPhysics()
syncWithDesigner()
}
panelPhysics()
}
function thisObjectPhysics () {
/* Screen Corner Date Calculation */
function panelPhysics () {
if (thisObject.container.frame.isInViewPort()) {
canvas.panelsSpace.makeVisible(thisObject.payload.node.id, 'Layers Panel')
} else {
canvas.panelsSpace.makeInvisible(thisObject.payload.node.id, 'Layers Panel')
}
}
let point = {
x: 0,
y: 0
function syncWithDesigner () {
syncWithDesignerTimelineCharts()
syncWithDesignerScales()
}
function syncWithDesignerScales () {
if (thisObject.payload.node === undefined) {
finalizeTimeScale()
finalizeRateScale()
finalizeTimeFrameScale()
return
}
if (thisObject.payload.node.timeScale === undefined && thisObject.timeScale !== undefined) {
finalizeTimeScale()
}
if (thisObject.payload.node.timeScale !== undefined && thisObject.timeScale === undefined) {
initializeTimeScale()
}
if (thisObject.payload.node.rateScale === undefined && thisObject.rateScale !== undefined) {
finalizeRateScale()
}
if (thisObject.payload.node.rateScale !== undefined && thisObject.rateScale === undefined) {
initializeRateScale()
}
if (thisObject.payload.node.timeFrameScale === undefined && thisObject.timeFrameScale !== undefined) {
finalizeTimeFrameScale()
}
if (thisObject.payload.node.timeFrameScale !== undefined && thisObject.timeFrameScale === undefined) {
initializeTimeFrameScale()
}
}
function syncWithDesignerTimelineCharts () {
syncWithDesignerLoop = syncWithDesignerLoop + 0.00000000001
for (let j = 0; j < thisObject.payload.node.timelineCharts.length; j++) {
let node = thisObject.payload.node.timelineCharts[j]
let timelineChart = timelineChartsMap.get(node.id)
if (timelineChart === undefined) {
/* The timeline timelineChart node is new, thus we need to initialize a new timelineChart */
initializeTimelineChart(node, syncWithDesignerLoop)
} else {
/* The time machine already exists, we tag it as existing at the current loop. */
timelineChart.syncWithDesignerLoop = syncWithDesignerLoop
}
}
let cornerDate = getDateFromPoint(point, thisObject.container, timeLineCoordinateSystem)
cornerDate = new Date(cornerDate)
window.localStorage.setItem('Date @ Screen Corner', cornerDate.toUTCString())
/* We check all the timeMachines we have to see if we need to remove any of them */
for (let i = 0; i < thisObject.timelineCharts.length; i++) {
let timelineChart = thisObject.timelineCharts[i]
if (timelineChart.syncWithDesignerLoop < syncWithDesignerLoop) {
/* Must be removed */
timelineChart.container.eventHandler.stopListening(timelineChart.onChildrenMouseOverEventSuscriptionId)
timelineChart.finalize()
timelineChartsMap.delete(timelineChart.nodeId)
thisObject.timelineCharts.splice(i, 1)
/* We remove one at the time */
return
}
}
function initializeTimelineChart (node, syncWithDesignerLoop) {
let timelineChart = newTimelineChart()
timelineChart.syncWithDesignerLoop = syncWithDesignerLoop
timelineChart.payload = node.payload
timelineChart.nodeId = node.id
timelineChartsMap.set(node.id, timelineChart)
timelineChart.payload.uiObject.setValue('Loading...')
/* Setting up the new timeline timelineChart. */
timelineChart.container.connectToParent(thisObject.container, true, true, false, true, true, true, false, false, true)
timelineChart.container.fitFunction = thisObject.container.fitFunction
timelineChart.fitFunction = thisObject.fitFunction
timelineChart.container.frame.width = thisObject.container.frame.width
timelineChart.container.frame.height = thisObject.container.frame.height
timelineChart.container.frame.position.x = 0
timelineChart.container.frame.position.y = 0
timelineChart.initialize(timeMachineCoordinateSystem)
/* we will store the event suscription id as a property of the timelineChart, to avoid keeping it an a separate array */
timelineChart.onChildrenMouseOverEventSuscriptionId = timelineChart.container.eventHandler.listenToEvent('onChildrenMouseOver', onChildrenMouseOver)
thisObject.timelineCharts.push(timelineChart)
timelineChart.payload.uiObject.setValue('')
function onChildrenMouseOver (event) {
thisObject.container.eventHandler.raiseEvent('onMouseOver', event)
}
}
}
function childrenPhysics () {
if (thisObject.timeScale === undefined) { return }
if (thisObject.rateScale === undefined) { return }
thisObject.timeScale.physics()
thisObject.rateScale.physics()
for (let i = 0; i < thisObject.charts.length; i++) {
let chart = thisObject.charts[i]
chart.physics()
if (thisObject.timeScale !== undefined) {
thisObject.timeScale.physics()
}
if (thisObject.rateScale !== undefined) {
thisObject.rateScale.physics()
}
if (thisObject.timeFrameScale !== undefined) {
thisObject.timeFrameScale.physics()
}
/* Mouse Position Date Calculation */
let timePoint = {
x: mouse.position.x,
y: 0
for (let i = 0; i < thisObject.timelineCharts.length; i++) {
let timelineChart = thisObject.timelineCharts[i]
timelineChart.physics()
}
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()
drawChartsBackground()
if (thisObject.container.frame.isInViewPort()) {
for (let i = 0; i < this.charts.length; i++) {
let chart = this.charts[i]
chart.drawBackground()
for (let i = 0; i < thisObject.timelineCharts.length; i++) {
let timelineChart = thisObject.timelineCharts[thisObject.timelineCharts.length - i - 1]
timelineChart.drawBackground()
}
}
}
function drawChartsBackground () {
drawContainerBackground(thisObject.container, UI_COLOR.WHITE, 0.5, thisObject.fitFunction)
}
function draw () {
if (thisObject.container.frame.isInViewPort()) {
for (let i = 0; i < this.charts.length; i++) {
let chart = this.charts[i]
chart.draw()
for (let i = 0; i < thisObject.timelineCharts.length; i++) {
let timelineChart = thisObject.timelineCharts[thisObject.timelineCharts.length - i - 1]
timelineChart.draw()
}
if (thisObject.timeScale !== undefined) { thisObject.timeScale.draw() }
if (thisObject.rateScale !== undefined) { thisObject.rateScale.draw() }
if (drawScales === true) {
if (thisObject.timeScale !== undefined && thisObject.timeScale.isVisible === true) { thisObject.timeScale.draw() }
if (thisObject.timeFrameScale !== undefined && thisObject.timeFrameScale.isVisible === true) { thisObject.timeFrameScale.draw() }
if (thisObject.rateScale !== undefined && thisObject.rateScale.isVisible === true) { thisObject.rateScale.draw() }
}
} else {
let icon = canvas.designerSpace.iconByUiObjectType.get(thisObject.payload.node.type)
if (icon !== undefined) {
if (icon.canDrawIcon === true) {
let imageSize = 40
let imagePosition = {
x: thisObject.container.frame.width / 2,
y: thisObject.container.frame.height / 2
}
// thisObject.container.frame.draw(false, true, false)
imagePosition = transformThisPoint(imagePosition, thisObject.container)
imagePosition = thisObject.fitFunction(imagePosition, true)
browserCanvasContext.drawImage(
icon,
imagePosition.x - imageSize / 2,
imagePosition.y - imageSize / 2,
imageSize,
imageSize)
}
}
}
}
function thisBackground () {
return
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
}
function drawForeground () {
if (thisObject.container.frame.isInViewPort()) {
for (let i = 0; i < thisObject.timelineCharts.length; i++) {
let timelineChart = thisObject.timelineCharts[thisObject.timelineCharts.length - i - 1]
timelineChart.drawForeground()
}
roundedCornersBackground(params)
if (drawScales === true) {
if (thisObject.timeScale !== undefined && thisObject.timeScale.isVisible === true) { thisObject.timeScale.drawForeground() }
if (thisObject.timeFrameScale !== undefined && thisObject.timeFrameScale.isVisible === true) { thisObject.timeFrameScale.drawForeground() }
if (thisObject.rateScale !== undefined && thisObject.rateScale.isVisible === true) { thisObject.rateScale.drawForeground() }
}
let style = {
color: UI_COLOR.BLACK,
opacity: 1,
lineWidth: 1,
lineDash: [1, 3]
}
thisObject.container.frame.draw(false, true, false, thisObject.fitFunction, style)
}
}
function recalculateScale () {
function recalculateCoordinateSystem () {
let minValue = {
x: MIN_PLOTABLE_DATE.valueOf(),
y: 0
@@ -388,10 +587,20 @@ function newTimeMachine () {
let maxValue = {
x: MAX_PLOTABLE_DATE.valueOf(),
y: nextPorwerOf10(USDT_BTC_HTH) / 4
y: nextPorwerOf10(MAX_DEFAULT_RATE_SCALE_VALUE) / 4
}
timeLineCoordinateSystem.initialize(
if (thisObject.timeScale !== undefined) {
minValue.x = thisObject.timeScale.fromDate
maxValue.x = thisObject.timeScale.toDate
}
if (thisObject.rateScale !== undefined) {
minValue.y = thisObject.rateScale.minValue
maxValue.y = thisObject.rateScale.maxValue
}
timeMachineCoordinateSystem.initialize(
minValue,
maxValue,
thisObject.container.frame.width,
+323 -427
View File
@@ -3,48 +3,57 @@ function newTimelineChart () {
const INFO_LOG = false
const INTENSIVE_LOG = false
const ERROR_LOG = true
const logger = newWebDebugLog()
let logger = newWebDebugLog()
logger.fileName = MODULE_NAME
let timeLineCoordinateSystem
let timePeriod = INITIAL_TIME_PERIOD
let timeFrame = INITIAL_TIME_PERIOD
let datetime = NEW_SESSION_INITIAL_DATE
let thisObject = {
container: undefined,
fitFunction: undefined,
physics: physics,
rateScale: undefined,
timeFrameScale: undefined,
payload: undefined,
layersManager: undefined,
plotterManager: undefined,
upstreamTimeFrame: undefined,
setDatetime: setDatetime,
drawBackground: drawBackground,
setTimeFrame: setTimeFrame,
physics: physics,
draw: draw,
drawBackground: drawBackground,
drawForeground: drawForeground,
getContainer: getContainer,
initialize: initialize,
finalize: finalize
}
thisObject.fitFunction = canvas.chartSpace.fitIntoVisibleArea
let timeMachineCoordinateSystem
let timelineChartCoordinateSystem = newCoordinateSystem()
let coordinateSystem
let initializationReady = false
let layersPanel
let layersPanelHandle
let productsPanel
let onMouseOverEventSuscriptionId
let onMouseNotOverEventSuscriptionId
let rateScaleValueEventSuscriptionId
let rateScaleUpstreamEventSuscriptionId
let rateScaleMouseOverEventSuscriptionId
let rateScaleOffsetEventSuscriptionId
let rateScaleUpstreamDimensionsEventSuscriptionId
let timeFrameScaleEventSuscriptionId
let timeFrameScaleMouseOverEventSuscriptionId
let scaleChangedEventSubscriptionId
/* 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
let drawScales = false
let mouse = {
position: {
x: 0,
y: 0
}
}
setupContainer()
return thisObject
@@ -56,192 +65,249 @@ function newTimelineChart () {
}
function finalize () {
plotterManager.finalize()
plotterManager = undefined
timePeriodScale.finalize()
timePeriodScale = undefined
canvas.panelsSpace.destroyPanel(productsPanelHandle)
coordinateSystem.eventHandler.stopListening(timelineChartCoordinateSystem)
if (thisObject.layersManager !== undefined) {
finalizeLayersManager()
}
if (thisObject.rateScale !== undefined) {
finalizeRateScale()
}
if (thisObject.timeFrameScale !== undefined) {
finalizeTimeFrameScale()
}
thisObject.container.eventHandler.stopListening(onMouseOverEventSuscriptionId)
thisObject.container.eventHandler.stopListening(onMouseNotOverEventSuscriptionId)
thisObject.container.finalize()
thisObject.container = undefined
setupContainer()
thisObject.payload = undefined
mouse = undefined
logger = undefined
timeMachineCoordinateSystem = undefined
timelineChartCoordinateSystem.finalize()
timelineChartCoordinateSystem = undefined
coordinateSystem = undefined
layersPanel = undefined
layersPanelHandle = undefined
}
function initialize (pExchange, pMarket, pTimeLineCoordinateSystem, callBackFunction) {
try {
if (INFO_LOG === true) { logger.write('[INFO] initialize -> Entering function.') }
function finalizeLayersManager () {
if (thisObject.plotterManager !== undefined) {
thisObject.plotterManager.finalize()
}
thisObject.plotterManager = undefined
thisObject.layersManager = undefined
/* We load the logow we will need for the background. */
exchange = pExchange
market = pMarket
timeLineCoordinateSystem = pTimeLineCoordinateSystem
canvas.panelsSpace.destroyPanel(layersPanelHandle)
}
thisObject.container.eventHandler.listenToEvent('onMouseOver', function (event) {
saveUserPosition(thisObject.container, timeLineCoordinateSystem, event)
})
function finalizeTimeFrameScale () {
if (thisObject.timeFrameScale === undefined) { return }
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
thisObject.timeFrameScale.container.eventHandler.stopListening(timeFrameScaleEventSuscriptionId)
thisObject.timeFrameScale.container.eventHandler.stopListening(timeFrameScaleMouseOverEventSuscriptionId)
thisObject.timeFrameScale.finalize()
thisObject.timeFrameScale = undefined
if (thisObject.upstreamTimeFrame !== undefined) {
timeFrame = thisObject.upstreamTimeFrame
if (thisObject.plotterManager !== undefined) {
thisObject.plotterManager.setTimeFrame(timeFrame)
}
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.fitFunction = thisObject.fitFunction
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.') }
function finalizeRateScale () {
if (thisObject.rateScale === undefined) { return }
if (initializationReady === true) {
recalculateCurrentDatetime()
thisObject.rateScale.container.eventHandler.stopListening(rateScaleOffsetEventSuscriptionId)
thisObject.rateScale.container.eventHandler.stopListening(rateScaleValueEventSuscriptionId)
thisObject.rateScale.container.eventHandler.stopListening(rateScaleMouseOverEventSuscriptionId)
thisObject.container.parentContainer.eventHandler.stopListening(rateScaleUpstreamEventSuscriptionId)
thisObject.container.parentContainer.eventHandler.stopListening(rateScaleUpstreamDimensionsEventSuscriptionId)
thisObject.rateScale.finalize()
thisObject.rateScale = undefined
// saveUserPosition(thisObject.container, timeLineCoordinateSystem)
/* Resets the local container with the dimessions of its parent, the Time Machine */
thisObject.container.frame.position.x = 0
thisObject.container.frame.position.y = 0
thisObject.container.frame.height = TIME_MACHINE_HEIGHT
thisObject.container.frame.width = TIME_MACHINE_WIDTH
}
function initialize (pTimeMachineCoordinateSystem) {
/* We load the logow we will need for the background. */
timeMachineCoordinateSystem = pTimeMachineCoordinateSystem
coordinateSystem = timeMachineCoordinateSystem
onScaleChanged()
timeFrame = INITIAL_TIME_PERIOD
onMouseOverEventSuscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver)
onMouseNotOverEventSuscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver)
scaleChangedEventSubscriptionId = timeMachineCoordinateSystem.eventHandler.listenToEvent('Scale Changed', onScaleChanged)
}
function initializeLayersManager () {
let owner = thisObject.payload.node.payload.parentNode.id // The real owner is the Time Machine
layersPanelHandle = canvas.panelsSpace.createNewPanel('Layers Panel', undefined, owner)
thisObject.layersManager = canvas.panelsSpace.getPanel(layersPanelHandle)
thisObject.layersManager.payload = thisObject.payload.node.layersManager.payload
thisObject.layersManager.initialize()
/* Initialize the Plotter Manager */
thisObject.plotterManager = newPlottersManager()
thisObject.plotterManager.container.connectToParent(thisObject.container, true, true, false, true, true, true, false, false, true)
thisObject.plotterManager.container.frame.position.x = 0
thisObject.plotterManager.container.frame.position.y = 0
thisObject.plotterManager.fitFunction = thisObject.fitFunction
thisObject.plotterManager.payload = thisObject.payload
thisObject.plotterManager.initialize(thisObject.layersManager)
thisObject.plotterManager.setTimeFrame(timeFrame)
thisObject.plotterManager.setDatetime(datetime)
thisObject.plotterManager.setCoordinateSystem(coordinateSystem)
}
function initializeRateScale () {
thisObject.rateScale = newRateScale()
thisObject.rateScale.fitFunction = thisObject.fitFunction
thisObject.rateScale.payload = thisObject.payload.node.rateScale.payload
rateScaleOffsetEventSuscriptionId = thisObject.rateScale.container.eventHandler.listenToEvent('Rate Scale Offset Changed', rateScaleOffsetChanged)
rateScaleValueEventSuscriptionId = thisObject.rateScale.container.eventHandler.listenToEvent('Rate Scale Value Changed', rateScaleValueChanged)
rateScaleMouseOverEventSuscriptionId = thisObject.rateScale.container.eventHandler.listenToEvent('onMouseOverScale', rateScaleMouseOver)
rateScaleUpstreamEventSuscriptionId = thisObject.container.parentContainer.eventHandler.listenToEvent('Upstream Rate Scale Value Changed', rateScaleUpstreamChanged)
rateScaleUpstreamDimensionsEventSuscriptionId = thisObject.container.parentContainer.eventHandler.listenToEvent('Dimmensions Changed', rateScaleUpstreamDimensioinsChanged)
thisObject.rateScale.initialize(timelineChartCoordinateSystem, thisObject.container.parentContainer, thisObject.container)
function rateScaleUpstreamDimensioinsChanged () {
thisObject.container.frame.height = TIME_MACHINE_HEIGHT + TIME_MACHINE_HEIGHT * thisObject.rateScale.scale
recalculateCoordinateSystem()
thisObject.container.eventHandler.raiseEvent('Dimmensions Changed', event)
}
function rateScaleUpstreamChanged (event) {
// thisObject.rateScale.setScale(event.scale)
}
function rateScaleOffsetChanged (event) {
if (thisObject.container.frame.offset.y !== event.offset) {
thisObject.container.frame.offset.y = event.offset
thisObject.container.eventHandler.raiseEvent('onDisplace')
}
}
function rateScaleValueChanged (event) {
thisObject.container.frame.height = TIME_MACHINE_HEIGHT + TIME_MACHINE_HEIGHT * event.scale
recalculateCoordinateSystem()
thisObject.container.eventHandler.raiseEvent('Dimmensions Changed', event)
}
function rateScaleMouseOver (event) {
thisObject.container.eventHandler.raiseEvent('onChildrenMouseOver', event)
}
}
function initializeTimeFrameScale () {
thisObject.timeFrameScale = newTimeFrameScale()
thisObject.timeFrameScale.fitFunction = thisObject.fitFunction
thisObject.timeFrameScale.payload = thisObject.payload.node.timeFrameScale.payload
timeFrameScaleEventSuscriptionId = thisObject.timeFrameScale.container.eventHandler.listenToEvent('Time Frame Value Changed', timeFrameScaleValueChanged)
timeFrameScaleMouseOverEventSuscriptionId = thisObject.timeFrameScale.container.eventHandler.listenToEvent('onMouseOverScale', timeFrameScaleMouseOver)
thisObject.timeFrameScale.initialize(thisObject.container.parentContainer)
function timeFrameScaleValueChanged (event) {
let currentTimeFrame = timeFrame
timeFrame = event.timeFrame
if (timeFrame !== currentTimeFrame) {
if (thisObject.plotterManager !== undefined) {
thisObject.plotterManager.setTimeFrame(timeFrame)
}
}
}
function timeFrameScaleMouseOver (event) {
thisObject.container.eventHandler.raiseEvent('onChildrenMouseOver', event)
}
}
function onScaleChanged () {
timelineChartCoordinateSystem.min.x = timeMachineCoordinateSystem.min.x
timelineChartCoordinateSystem.max.x = timeMachineCoordinateSystem.max.x
timelineChartCoordinateSystem.recalculateScale()
}
function setTimeFrame (pTimeFrame) {
timeFrame = pTimeFrame
if (thisObject.plotterManager !== undefined) {
thisObject.plotterManager.setTimeFrame(timeFrame)
}
}
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)
datetime = pDatetime
if (thisObject.plotterManager !== undefined) {
thisObject.plotterManager.setDatetime(datetime)
}
}
function onOffsetChanged () {
if (INFO_LOG === true) { logger.write('[INFO] onOffsetChanged -> Entering function.') }
function onMouseOver (event) {
/* This event gets to the timelinechart container because it inherits it from the time machine container, which is the one raising Mouse Over and Mouse not Over Events to its children. */
drawScales = true
if (initializationReady === true) {
if (thisObject.container.frame.isInViewPort()) {
recalculateCurrentDatetime()
// saveUserPosition(thisObject.container, timeLineCoordinateSystem)
}
if (thisObject.rateScale !== undefined) {
thisObject.rateScale.onMouseOverSomeTimeMachineContainer(event)
}
if (thisObject.timeFrameScale !== undefined) {
thisObject.timeFrameScale.onMouseOverSomeTimeMachineContainer(event)
}
mouse.position.x = event.x
mouse.position.y = event.y
}
function onMouseNotOver (event) {
/* This event is inherited from the Time Machine */
drawScales = false
if (thisObject.rateScale !== undefined) {
thisObject.rateScale.visible = false
}
if (thisObject.timeFrameScale !== undefined) {
thisObject.timeFrameScale.visible = false
}
}
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.') }
function getContainer (point, purpose) {
let container
container = timePeriodScale.getContainer(point)
if (thisObject.rateScale !== undefined && thisObject.rateScale.isVisible === true) {
container = thisObject.rateScale.getContainer(point)
if (container !== undefined) {
if (container.isForThisPurpose(purpose)) {
return container
}
}
}
if (container !== undefined) { return container }
if (thisObject.timeFrameScale !== undefined && thisObject.timeFrameScale.isVisible === true) {
container = thisObject.timeFrameScale.getContainer(point)
if (container !== undefined) {
if (container.isForThisPurpose(purpose)) {
return container
}
}
}
return container
}
@@ -249,283 +315,113 @@ function newTimelineChart () {
function physics () {
thisObjectPhysics()
childrenPhysics()
syncWithDesignerScales()
syncWithDesignerLayersManager()
}
function thisObjectPhysics () {
}
function childrenPhysics () {
function syncWithDesignerLayersManager () {
if (thisObject.payload.node === undefined) {
finalizeLayersManager()
return
}
}
function tooTiny () {
if (viewPort.zoomLevel < Math.trunc(-28.25 * 100) / 100) {
return true
} else {
return false
if (thisObject.payload.node.layersManager === undefined && thisObject.layersManager !== undefined) {
finalizeLayersManager()
}
if (thisObject.payload.node.layersManager !== undefined && thisObject.layersManager === undefined) {
initializeLayersManager()
}
}
function tooSmall () {
if (viewPort.zoomLevel < Math.trunc(-27.25 * 100) / 100) {
return true
} else {
return false
function syncWithDesignerScales () {
if (thisObject.payload.node === undefined) {
finalizeRateScale()
finalizeTimeFrameScale()
return
}
if (thisObject.payload.node.rateScale === undefined && thisObject.rateScale !== undefined) {
finalizeRateScale()
coordinateSystem = timeMachineCoordinateSystem
}
if (thisObject.payload.node.rateScale !== undefined && thisObject.rateScale === undefined) {
initializeRateScale()
coordinateSystem = timelineChartCoordinateSystem
}
if (thisObject.payload.node.timeFrameScale === undefined && thisObject.timeFrameScale !== undefined) {
finalizeTimeFrameScale()
}
if (thisObject.payload.node.timeFrameScale !== undefined && thisObject.timeFrameScale === undefined) {
initializeTimeFrameScale()
}
}
function childrenPhysics () {
if (thisObject.rateScale !== undefined) {
thisObject.rateScale.layersOn = thisObject.plotterManager.connectors.length
thisObject.rateScale.physics()
}
if (thisObject.timeFrameScale !== undefined) {
thisObject.timeFrameScale.layersOn = thisObject.plotterManager.connectors.length
thisObject.timeFrameScale.physics()
}
}
function drawBackground () {
if (thisObject.container.frame.isInViewPort()) {
if (window.CHART_ON_FOCUS === '') {
window.CHART_ON_FOCUS = exchange + ' ' + market.assetB + '/' + market.assetA
drawChartsBackgroundImages()
drawChartsBackground()
if (thisObject.plotterManager !== undefined) {
thisObject.plotterManager.draw()
}
}
}
function draw () {
if (thisObject.container.frame.isInViewPort()) {
drawChartsBackground()
plotterManager.draw()
timePeriodScale.draw()
if (drawScales === true) {
if (thisObject.timeFrameScale !== undefined && thisObject.timeFrameScale.isVisible === true) { thisObject.timeFrameScale.draw() }
if (thisObject.rateScale !== undefined && thisObject.rateScale.isVisible === true) { thisObject.rateScale.draw() }
}
}
}
function drawForeground () {
if (thisObject.container.frame.isInViewPort()) {
if (drawScales === true) {
if (thisObject.timeFrameScale !== undefined && thisObject.timeFrameScale.isVisible === true) { thisObject.timeFrameScale.drawForeground() }
if (thisObject.rateScale !== undefined && thisObject.rateScale.isVisible === true) { thisObject.rateScale.drawForeground() }
}
}
}
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()
drawContainerBackground(thisObject.container, UI_COLOR.WHITE, 0, thisObject.fitFunction)
}
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,
function recalculateCoordinateSystem () {
let minValue = {
x: timelineChartCoordinateSystem.min.x,
y: 0
}
let toPoint = {
x: thisObject.container.frame.width,
y: thisObject.container.frame.height
let maxValue = {
x: timelineChartCoordinateSystem.max.x,
y: nextPorwerOf10(MAX_DEFAULT_RATE_SCALE_VALUE) / 4
}
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 = 32
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
if (thisObject.rateScale !== undefined) {
minValue.y = thisObject.rateScale.minValue
maxValue.y = thisObject.rateScale.maxValue
}
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)
}
}
}
}
timelineChartCoordinateSystem.initialize(
minValue,
maxValue,
thisObject.container.frame.width,
thisObject.container.frame.height
)
}
}
+200 -285
View File
@@ -1,20 +1,17 @@
function newViewPort () {
function newViewport () {
const MODULE_NAME = 'Viewport'
const INFO_LOG = false
const INTENSIVE_LOG = false
const ERROR_LOG = true
const logger = newWebDebugLog()
logger.fileName = MODULE_NAME
const CONSOLE_LOG = true
const MIN_ZOOM_LEVEL = 0
const MAX_ZOOM_LEVEL = 500
let ANIMATION_INCREMENT = 0.25
let ANIMATION_STEPS = 5
let TOP_MARGIN = 30 + TOP_SPACE_HEIGHT
let BOTTOM_MARGIN = 30 + COCKPIT_SPACE_HEIGHT
let LEFT_MARGIN = 50
let RIGHT_MARGIN = 50
let TOP_MARGIN = 40 + TOP_SPACE_HEIGHT
let BOTTOM_MARGIN = 42 + COCKPIT_SPACE_HEIGHT
let LEFT_MARGIN = 0
let RIGHT_MARGIN = 0
let MARGINS = {
TOP: TOP_MARGIN,
BOTTOM: BOTTOM_MARGIN,
@@ -31,60 +28,78 @@ function newViewPort () {
zoomLevel: undefined,
mousePosition: undefined,
margins: MARGINS,
getDisplacement: getDisplacement,
newZoomLevel: newZoomLevel,
applyZoom: applyZoom,
isMinZoom: isMinZoom,
zoomFontSize: zoomFontSize,
zoomThisPoint: zoomThisPoint,
unzoomThisPoint: unzoomThisPoint,
payload: undefined,
changeZoom: changeZoom,
onMouseWheel: onMouseWheel,
transformThisPoint: transformThisPoint,
unTransformThisPoint: unTransformThisPoint,
isThisPointVisible: isThisPointVisible,
fitIntoVisibleArea: fitIntoVisibleArea,
displace: displace,
displaceTarget: displaceTarget,
animate: animate,
draw: draw,
physics: physics,
raiseEvents: raiseEvents,
resize: resize,
initialize: initialize
initialize: initialize,
finalize: finalize
}
let increment = 0.035
let offset = {
let position = {
x: 0,
y: 0
}
var targetOffset = {
let targetPosition = {
x: 0,
y: 0
}
let offsetIncrement = {
let positionIncrement = {
x: 0,
y: 0
}
thisObject.mousePosition = {
x: 0,
y: 0
}
thisObject.eventHandler = newEventHandler()
let objectStorage = {}
/* Initial default value */
thisObject.zoomLevel = MIN_ZOOM_LEVEL
thisObject.zoomTargetLevel = MIN_ZOOM_LEVEL
INITIAL_TIME_PERIOD = recalculatePeriod(thisObject.zoomLevel)
return thisObject
function finalize () {
thisObject.eventHandler.finalize()
thisObject.payload = undefined
thisObject = undefined
}
function initialize () {
if (thisObject.payload !== undefined) {
/* Read the position from the frame structure */
let frame = {
position: {
x: 0,
y: 0
}
}
loadFrame(thisObject.payload, frame)
if (!isNaN(frame.position.x)) {
position.x = frame.position.x
}
if (!isNaN(frame.position.y)) {
position.y = frame.position.y
}
}
resize()
readObjectState()
}
function resize () {
TOP_MARGIN = 30 + TOP_SPACE_HEIGHT
BOTTOM_MARGIN = 30 + browserCanvas.height - COCKPIT_SPACE_POSITION
TOP_MARGIN = 40 + TOP_SPACE_HEIGHT
BOTTOM_MARGIN = 42 + browserCanvas.height - COCKPIT_SPACE_POSITION
LEFT_MARGIN = 0
RIGHT_MARGIN = 0
MARGINS = {
@@ -103,25 +118,36 @@ function newViewPort () {
thisObject.width = thisObject.visibleArea.topRight.x - thisObject.visibleArea.topLeft.x
thisObject.height = thisObject.visibleArea.bottomRight.y - thisObject.visibleArea.topLeft.y
}
function getDisplacement () {
let displacement = {
x: offset.x,
y: offset.y
thisObject.center = {
x: LEFT_MARGIN + thisObject.width / 2,
y: TOP_MARGIN + thisObject.height / 2
}
return displacement
}
function raiseEvents () {
let event = {
newOffset: offset
newPosition: position
}
thisObject.eventHandler.raiseEvent('Offset Changed', event)
thisObject.eventHandler.raiseEvent('Position Changed', event)
}
function animate () {
function physics () {
animationPhysics()
positioningPhysics()
readObjectState()
}
function positioningPhysics () {
if (thisObject.payload === undefined) { return }
/* Save the position at the frame lavel */
let frame = {}
frame.position = position
saveFrame(thisObject.payload, frame)
}
function animationPhysics () {
if (thisObject.zoomLevel < thisObject.zoomTargetLevel) {
if (thisObject.zoomTargetLevel - thisObject.zoomLevel < ANIMATION_INCREMENT) {
ANIMATION_INCREMENT = Math.abs(thisObject.zoomTargetLevel - thisObject.zoomLevel)
@@ -138,174 +164,60 @@ function newViewPort () {
changeZoom(thisObject.zoomLevel + ANIMATION_INCREMENT, thisObject.zoomLevel)
}
if (offsetIncrement.y !== 0) {
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)
if (positionIncrement.y !== 0) {
if (Math.trunc(Math.abs(targetPosition.y - position.y) * 1000) >= Math.trunc(Math.abs(positionIncrement.y) * 1000)) {
position.y = position.y + positionIncrement.y
} else {
offsetIncrement.y = 0
positionIncrement.y = 0
}
}
}
function displace (displaceVector, recalculate) {
offset.x = offset.x + displaceVector.x
offset.y = offset.y + displaceVector.y
saveObjectState()
let event = {
newOffset: offset,
recalculate: recalculate
}
thisObject.eventHandler.raiseEvent('Offset Changed', event)
// console.log("displace produced new Offset x = " + offset.x + " y = " + offset.y);
}
function displaceTarget (displaceVector) {
targetOffset.x = targetOffset.x + displaceVector.x
targetOffset.y = targetOffset.y + displaceVector.y
offsetIncrement = {
x: (targetOffset.x - offset.x) / 10,
y: (targetOffset.y - offset.y) / 10
}
// console.log("displaceTarget x = " + targetOffset.x + " y = " + targetOffset.y);
}
function newZoomLevel (level) {
thisObject.zoomTargetLevel = level
thisObject.zoomLevel = level
saveObjectState()
ANIMATION_INCREMENT = Math.abs(thisObject.zoomTargetLevel - thisObject.zoomLevel) / 3
let event = {
newLevel: thisObject.zoomTargetLevel,
newOffset: offset,
type: undefined
}
thisObject.eventHandler.raiseEvent('Zoom Changed', event)
return true
}
function isMinZoom () {
/* 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);
function onMouseWheel (event) {
let morePower = 1
let amount = event.delta
if (event.buttons === 4) { morePower = 2 } // Mouse wheel pressed.
/* We adjust the sensitivity for Mac Users */
let isMac = navigator.platform.toUpperCase().indexOf('MAC') >= 0
if (isMac) { amount = amount / 5 }
if (amount > 0) {
if (thisObject.zoomTargetLevel > -5) {
amount = amount * 2
}
if (thisObject.zoomTargetLevel > 10) {
amount = amount * 3
}
if (thisObject.zoomTargetLevel > 15) {
amount = amount * 4
}
if (thisObject.zoomTargetLevel > 10) {
amount = amount * 2
}
if (thisObject.zoomTargetLevel > 25) {
amount = amount * 3
}
if (thisObject.zoomTargetLevel > 50) {
amount = amount * 3.5
}
if (amount < 0) {
if (thisObject.zoomTargetLevel > -4) {
amount = amount * 2
}
if (thisObject.zoomTargetLevel > 13) {
amount = amount * 3
}
if (thisObject.zoomTargetLevel > 19) {
amount = amount * 4
}
}
if (thisObject.zoomTargetLevel + amount > 1000) {
if (thisObject.zoomTargetLevel + amount * morePower > MAX_ZOOM_LEVEL) {
return false
}
if (thisObject.zoomTargetLevel <= -27 && amount < 0) {
amount = amount / 4
}
if (thisObject.zoomTargetLevel < -27 && amount > 0) {
amount = amount / 4
}
if (thisObject.zoomTargetLevel + amount < MIN_ZOOM_LEVEL) {
if (thisObject.zoomTargetLevel + amount * morePower < MIN_ZOOM_LEVEL) {
return false
}
thisObject.zoomTargetLevel = thisObject.zoomTargetLevel + amount * morePower
thisObject.zoomTargetLevel = thisObject.zoomTargetLevel + amount
ANIMATION_INCREMENT = Math.abs(thisObject.zoomTargetLevel - thisObject.zoomLevel) / ANIMATION_STEPS
ANIMATION_INCREMENT = Math.abs(thisObject.zoomTargetLevel - thisObject.zoomLevel) / 3
let event = {
let newEvent = {
newLevel: thisObject.zoomTargetLevel,
newOffset: offset,
type: undefined
newPosition: position,
type: undefined,
shiftKey: event.shiftKey
}
if (amount > 0) {
event.type = 'Zoom In'
newEvent.type = 'Zoom In'
} else {
event.type = 'Zoom Out'
newEvent.type = 'Zoom Out'
}
thisObject.eventHandler.raiseEvent('Zoom Changed', event)
thisObject.eventHandler.raiseEvent('Zoom Changed', newEvent)
return true
}
function changeZoom (oldLevel, newLevel) {
let mouseNoZoom = unzoomThisPoint(thisObject.mousePosition, oldLevel)
let newMouse = zoomThisPoint(mouseNoZoom, newLevel)
offset.x = offset.x - newMouse.x + thisObject.mousePosition.x
offset.y = offset.y - newMouse.y + thisObject.mousePosition.y
saveObjectState()
targetOffset.x = offset.x
targetOffset.y = offset.y
offsetIncrement = {
x: 0,
y: 0
}
thisObject.eventHandler.raiseEvent('Zoom Changed')
}
function zoomFontSize (baseSize, level) {
let zoomFactor = increment // + increment * thisObject.zoomLevel / 100;
if (level === undefined) {
baseSize = baseSize * (1 + zoomFactor * thisObject.zoomLevel)
} else {
baseSize = baseSize * (1 + zoomFactor * level)
}
return baseSize
}
function fitIntoVisibleArea (point) {
/* Here we check the boundaries of the resulting points, so they dont go out of the visible area. */
@@ -328,35 +240,72 @@ function newViewPort () {
return point
}
function zoomThisPoint (point, level) {
let zoomFactor = increment // + increment * thisObject.zoomLevel / 100;
function displace (displaceVector, recalculate) {
position.x = position.x + displaceVector.x
position.y = position.y + displaceVector.y
if (level === undefined) {
point.x = point.x * (1 + zoomFactor * thisObject.zoomLevel) + offset.x
point.y = point.y * (1 + zoomFactor * thisObject.zoomLevel) + offset.y
} else {
point.x = point.x * (1 + zoomFactor * level) + offset.x
point.y = point.y * (1 + zoomFactor * level) + offset.y
saveObjectState()
let event = {
newPosition: position,
recalculate: recalculate
}
return point
thisObject.eventHandler.raiseEvent('Position Changed', event)
}
function unzoomThisPoint (pointWithZoom, level) {
let pointWithoutZoom
let zoomFactor = increment // + increment * thisObject.zoomLevel / 100;
function changeZoom (oldLevel, newLevel) {
let oldMouse = unTransformThisPoint(thisObject.mousePosition, oldLevel)
let newMouse = transformThisPoint(oldMouse, newLevel)
position.x = position.x - newMouse.x + thisObject.mousePosition.x
position.y = position.y - newMouse.y + thisObject.mousePosition.y
let testPoint = unTransformThisPoint(thisObject.mousePosition, newLevel)
saveObjectState()
targetPosition.x = position.x
targetPosition.y = position.y
positionIncrement = {
x: 0,
y: 0
}
thisObject.eventHandler.raiseEvent('Zoom Changed')
}
function transformThisPoint (point, level) {
let transformedPoint = {
x: 0,
y: 0
}
if (level === undefined) {
pointWithoutZoom = {
x: (pointWithZoom.x - offset.x) / (1 + zoomFactor * thisObject.zoomLevel),
y: (pointWithZoom.y - offset.y) / (1 + zoomFactor * thisObject.zoomLevel)
}
transformedPoint.x = point.x * (1 + thisObject.zoomLevel) + position.x
transformedPoint.y = point.y * (1 + thisObject.zoomLevel) + position.y
} else {
pointWithoutZoom = {
x: (pointWithZoom.x - offset.x) / (1 + zoomFactor * level),
y: (pointWithZoom.y - offset.y) / (1 + zoomFactor * level)
}
transformedPoint.x = point.x * (1 + level) + position.x
transformedPoint.y = point.y * (1 + level) + position.y
}
return transformedPoint
}
function unTransformThisPoint (point, level) {
let pointWithoutZoom = {
x: 0,
y: 0
}
if (level === undefined) {
pointWithoutZoom.x = (point.x - position.x) / (1 + thisObject.zoomLevel)
pointWithoutZoom.y = (point.y - position.y) / (1 + thisObject.zoomLevel)
} else {
pointWithoutZoom.x = (point.x - position.x) / (1 + level)
pointWithoutZoom.y = (point.y - position.y) / (1 + level)
}
return pointWithoutZoom
}
@@ -372,92 +321,58 @@ function newViewPort () {
}
}
function draw () {
drawGrid(0.1)
}
function drawGrid (step) {
if (thisObject.zoomLevel > -17) { return }
let squareWidth = (thisObject.visibleArea.bottomRight.x - thisObject.visibleArea.bottomLeft.x) / step
squareWidth = squareWidth + squareWidth * increment * thisObject.zoomLevel
let startingX = offset.x - Math.trunc(offset.x / squareWidth) * squareWidth
let startingY = offset.y - Math.trunc(offset.y / squareWidth) * squareWidth
let lineWidth = 0.4 + thisObject.zoomLevel / 100
lineWidth = lineWidth.toFixed(2)
if (lineWidth < 0.1) {
return
}
if (lineWidth > 2) {
lineWidth = 2
}
browserCanvasContext.beginPath()
let CROSS_SIZE = 4
for (var i = startingX; i < thisObject.visibleArea.bottomRight.x + RIGHT_MARGIN; i = i + squareWidth) {
for (var j = startingY; j < thisObject.visibleArea.bottomRight.y + BOTTOM_MARGIN; j = j + squareWidth) {
let point1 = {
x: Math.trunc(i - CROSS_SIZE),
y: Math.trunc(j)
}
let point2 = {
x: Math.trunc(i + CROSS_SIZE),
y: Math.trunc(j)
}
browserCanvasContext.moveTo(point1.x, point1.y)
browserCanvasContext.lineTo(point2.x, point2.y)
let point3 = {
x: Math.trunc(i),
y: Math.trunc(j - CROSS_SIZE)
}
let point4 = {
x: Math.trunc(i),
y: Math.trunc(j + CROSS_SIZE)
}
browserCanvasContext.moveTo(point3.x, point3.y)
browserCanvasContext.lineTo(point4.x, point4.y)
}
}
browserCanvasContext.closePath()
browserCanvasContext.strokeStyle = 'rgba(150, 150, 150, 0.5)'
browserCanvasContext.lineWidth = 1
browserCanvasContext.stroke()
}
function saveObjectState () {
objectStorage.offset = offset
objectStorage.zoomLevel = thisObject.zoomLevel
window.localStorage.setItem(MODULE_NAME, JSON.stringify(objectStorage))
if (thisObject.payload === undefined) { return }
/* Save the zoom at the node config, so that the user can change it if he wishes to. */
try {
let code = JSON.parse(thisObject.payload.node.code)
code.zoom = (thisObject.zoomTargetLevel - MIN_ZOOM_LEVEL) / (MAX_ZOOM_LEVEL - MIN_ZOOM_LEVEL) * 100
code.zoom = code.zoom.toFixed(2)
thisObject.payload.node.code = JSON.stringify(code)
} catch (err) {
// we ignore errors here since most likely they will be parsing errors.
}
}
function readObjectState () {
let objectStorageString = window.localStorage.getItem(MODULE_NAME)
if (objectStorageString !== null && objectStorageString !== '') {
objectStorage = JSON.parse(objectStorageString)
offset = objectStorage.offset
thisObject.zoomLevel = objectStorage.zoomLevel
thisObject.zoomTargetLevel = objectStorage.zoomLevel
INITIAL_TIME_PERIOD = recalculatePeriod(thisObject.zoomLevel)
} else { // Setting default values for first session
offset = {
x: 0,
y: 0
if (thisObject.payload === undefined) { return }
/* Read the zoom level from the node config */
try {
let code = JSON.parse(thisObject.payload.node.code)
if (isNaN(code.zoom) || code.zoom === null || code.zoom === undefined) {
saveObjectState()
return
}
thisObject.zoomLevel = MIN_ZOOM_LEVEL
thisObject.zoomTargetLevel = MIN_ZOOM_LEVEL
code.zoom = code.zoom / 100 * (MAX_ZOOM_LEVEL - MIN_ZOOM_LEVEL) + MIN_ZOOM_LEVEL
if (code.zoom < MIN_ZOOM_LEVEL) { code.zoom = MIN_ZOOM_LEVEL }
if (code.zoom > MAX_ZOOM_LEVEL) { code.zoom = MAX_ZOOM_LEVEL }
if (code.zoom.toFixed(2) !== thisObject.zoomTargetLevel.toFixed(2)) {
newZoomLevel(code.zoom)
} else {
saveObjectState()
}
} catch (err) {
// we ignore errors here since most likely they will be parsing errors.
}
function newZoomLevel (level) {
thisObject.zoomLevel = level
thisObject.zoomTargetLevel = level
INITIAL_TIME_PERIOD = recalculatePeriod(level)
saveObjectState()
ANIMATION_INCREMENT = 0
let event = {
newLevel: thisObject.zoomTargetLevel,
newPosition: position,
type: undefined
}
thisObject.eventHandler.raiseEvent('Zoom Changed', event)
return true
}
}
}
+5 -7
View File
@@ -1,5 +1,5 @@
function newAssetBalances () {
function newQuotedAssetalances () {
const MODULE_NAME = 'Asset Balances'
let thisObject = {
@@ -37,9 +37,6 @@ function newAssetBalances () {
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)
}
@@ -87,10 +84,10 @@ function newAssetBalances () {
speedometer.draw()
}
drawAssetBalances()
drawQuotedAssetalances()
}
function drawAssetBalances () {
function drawQuotedAssetalances () {
if (thisObject.paramsArray === undefined) { return }
let fontSize
@@ -109,7 +106,7 @@ function newAssetBalances () {
label = 'ASSET BALANCES'
xOffset = label.length / 2 * fontSize * FONT_ASPECT_RATIO
yOffset = -45
yOffset = -45 + 9
labelPoint = {
x: 0 - xOffset + (thisObject.paramsArray[1].LEFT_OFFSET - thisObject.paramsArray[0].LEFT_OFFSET) / 2 + thisObject.paramsArray[0].LEFT_OFFSET - 20,
@@ -120,3 +117,4 @@ function newAssetBalances () {
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y)
}
}
+1 -1
View File
@@ -28,7 +28,7 @@ function newFullScreen () {
let isMouseOver = false
let counterTillNextState = 0
let productCardsToTurnOn = []
let layersToTurnOn = []
return thisObject
function finalize () {
+14 -14
View File
@@ -51,24 +51,24 @@ function newSpeedometer () {
}
function drawAssetCircle () {
const RED_LINE_HIGHT = 5
const RADIOUS = 50
const RED_LINE_HIGHT = 2
const RADIUS = 50
const OPACITY = 1
let centerPoint = {
x: thisObject.params.LEFT_OFFSET,
y: COCKPIT_SPACE_POSITION - COCKPIT_SPACE_HEIGHT / 2
y: COCKPIT_SPACE_POSITION - COCKPIT_SPACE_HEIGHT / 2 - 9
}
browserCanvasContext.beginPath()
browserCanvasContext.arc(centerPoint.x, centerPoint.y, RADIOUS + RED_LINE_HIGHT, 0.85 * Math.PI, 2.15 * Math.PI)
browserCanvasContext.arc(centerPoint.x, centerPoint.y, RADIUS + 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.arc(centerPoint.x, centerPoint.y, RADIUS, 0.0 * Math.PI, 2.0 * Math.PI)
browserCanvasContext.closePath()
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.DARK_TURQUOISE + ', ' + OPACITY + ')'
@@ -79,7 +79,7 @@ function newSpeedometer () {
const DEFAULT_THICKNESS = 2
const VALUE_THICKNESS = 8
const VALUE_BG_THICKNESS = 1
const BAR_RADIOUS = RADIOUS * 0.85
const BAR_RADIUS = RADIUS * 0.85
let BAR_START_ANGLE = 0.85 * Math.PI
let BAR_END_ANGLE = 2.15 * Math.PI
@@ -100,7 +100,7 @@ function newSpeedometer () {
browserCanvasContext.setLineDash([0, 0])
browserCanvasContext.beginPath()
browserCanvasContext.arc(centerPoint.x, centerPoint.y, BAR_RADIOUS, BAR_START_ANGLE, MIN_VALUE_ANGLE)
browserCanvasContext.arc(centerPoint.x, centerPoint.y, BAR_RADIUS, BAR_START_ANGLE, MIN_VALUE_ANGLE)
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', ' + OPACITY + ')'
browserCanvasContext.lineWidth = VALUE_BG_THICKNESS
@@ -108,7 +108,7 @@ function newSpeedometer () {
browserCanvasContext.closePath()
browserCanvasContext.beginPath()
browserCanvasContext.arc(centerPoint.x, centerPoint.y, BAR_RADIOUS, MIN_VALUE_ANGLE, CURRENT_VALUE_ANGLE)
browserCanvasContext.arc(centerPoint.x, centerPoint.y, BAR_RADIUS, MIN_VALUE_ANGLE, CURRENT_VALUE_ANGLE)
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + OPACITY + ')'
browserCanvasContext.lineWidth = VALUE_BG_THICKNESS
@@ -116,7 +116,7 @@ function newSpeedometer () {
browserCanvasContext.closePath()
browserCanvasContext.beginPath()
browserCanvasContext.arc(centerPoint.x, centerPoint.y, BAR_RADIOUS, CURRENT_VALUE_ANGLE, INIT_VALUE_ANGLE)
browserCanvasContext.arc(centerPoint.x, centerPoint.y, BAR_RADIUS, CURRENT_VALUE_ANGLE, INIT_VALUE_ANGLE)
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.RED + ', ' + OPACITY + ')'
browserCanvasContext.lineWidth = VALUE_BG_THICKNESS
@@ -125,7 +125,7 @@ function newSpeedometer () {
if (PROFIT_VALUE_ANGLE > INIT_VALUE_ANGLE) {
browserCanvasContext.beginPath()
browserCanvasContext.arc(centerPoint.x, centerPoint.y, BAR_RADIOUS, INIT_VALUE_ANGLE, PROFIT_VALUE_ANGLE)
browserCanvasContext.arc(centerPoint.x, centerPoint.y, BAR_RADIUS, INIT_VALUE_ANGLE, PROFIT_VALUE_ANGLE)
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.GREEN + ', ' + OPACITY + ')'
browserCanvasContext.lineWidth = VALUE_BG_THICKNESS
@@ -136,7 +136,7 @@ function newSpeedometer () {
browserCanvasContext.setLineDash([2, 3])
browserCanvasContext.beginPath()
browserCanvasContext.arc(centerPoint.x, centerPoint.y, BAR_RADIOUS, BAR_START_ANGLE, MIN_VALUE_ANGLE)
browserCanvasContext.arc(centerPoint.x, centerPoint.y, BAR_RADIUS, BAR_START_ANGLE, MIN_VALUE_ANGLE)
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', ' + OPACITY + ')'
browserCanvasContext.lineWidth = VALUE_THICKNESS
@@ -144,7 +144,7 @@ function newSpeedometer () {
browserCanvasContext.closePath()
browserCanvasContext.beginPath()
browserCanvasContext.arc(centerPoint.x, centerPoint.y, BAR_RADIOUS, MIN_VALUE_ANGLE, CURRENT_VALUE_ANGLE)
browserCanvasContext.arc(centerPoint.x, centerPoint.y, BAR_RADIUS, MIN_VALUE_ANGLE, CURRENT_VALUE_ANGLE)
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + OPACITY + ')'
browserCanvasContext.lineWidth = VALUE_THICKNESS
@@ -152,7 +152,7 @@ function newSpeedometer () {
browserCanvasContext.closePath()
browserCanvasContext.beginPath()
browserCanvasContext.arc(centerPoint.x, centerPoint.y, BAR_RADIOUS, CURRENT_VALUE_ANGLE, INIT_VALUE_ANGLE)
browserCanvasContext.arc(centerPoint.x, centerPoint.y, BAR_RADIUS, CURRENT_VALUE_ANGLE, INIT_VALUE_ANGLE)
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.RED + ', ' + OPACITY + ')'
browserCanvasContext.lineWidth = VALUE_THICKNESS
@@ -161,7 +161,7 @@ function newSpeedometer () {
if (PROFIT_VALUE_ANGLE > INIT_VALUE_ANGLE) {
browserCanvasContext.beginPath()
browserCanvasContext.arc(centerPoint.x, centerPoint.y, BAR_RADIOUS, INIT_VALUE_ANGLE, PROFIT_VALUE_ANGLE)
browserCanvasContext.arc(centerPoint.x, centerPoint.y, BAR_RADIUS, INIT_VALUE_ANGLE, PROFIT_VALUE_ANGLE)
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.GREEN + ', ' + OPACITY + ')'
browserCanvasContext.lineWidth = VALUE_THICKNESS
+10 -7
View File
@@ -4,7 +4,6 @@ function newContainer () {
id: Math.trunc(Math.random() * 10000000),
type: 'Rectangle',
frame: undefined,
displacement: undefined,
eventHandler: undefined,
parentContainer: undefined,
isDraggeable: true,
@@ -62,6 +61,8 @@ function newContainer () {
thisObject.parentContainer = undefined
thisObject.eventHandler.finalize()
thisObject.frame.finalize()
}
}
@@ -71,15 +72,13 @@ function newContainer () {
thisObject.frame = newFrame()
thisObject.frame.initialize(pType)
thisObject.frame.containerName = pName
if (pName !== undefined) {
thisObject.frame.containerName = pName
}
thisObject.frame.container = thisObject
thisObject.eventHandler = newEventHandler()
thisObject.eventHandler.name = pName
thisObject.displacement = newDisplacement()
thisObject.displacement.container = thisObject
thisObject.displacement.containerName = pName
}
function connectToParent (
@@ -111,7 +110,6 @@ function newContainer () {
isConnectedToParent = true
thisObject.displacement.parentDisplacement = parentContainer.displacement
thisObject.frame.parentFrame = parentContainer.frame
thisObject.parentContainer = parentContainer
@@ -217,6 +215,11 @@ function newContainer () {
return true
}
break
case GET_CONTAINER_PURPOSE.DRAGGING:
if (thisObject.isDraggeable === true) {
return true
}
break
default: { return false }
}
+1 -1
View File
@@ -26,7 +26,7 @@ function newSidePanel () {
thisObject.sidePanelTab.container.connectToParent(thisObject.container, false, false)
thisObject.sidePanelTab.initialize()
window.canvasApp.eventHandler.listenToEvent('Browser Resized', resize)
canvas.eventHandler.listenToEvent('Browser Resized', resize)
isInitialized = true
}
+9 -45
View File
@@ -2,7 +2,7 @@ let canvas
let markets
let ecosystem = newEcosystem()
let systemEventHandler
let viewPort
let APP_SCHEMA_MAP = new Map()
let APP_SCHEMA_ARRAY = []
@@ -19,17 +19,12 @@ function newDashboard () {
const DEBUG_START_UP_DELAY = 0 // 3000; // This is a waiting time in case there is a need to debug the very first steps of initialization, to be able to hit F12 on time.
let userProfileChangedEventSubscriptionId
let browserResizedEventSubscriptionId
return thisObject
function start () {
try {
setBrowserEvents()
viewPort = newViewPort()
systemEventHandler = newSystemEventHandler()
systemEventHandler.initialize(setUpAppSchema)
@@ -37,12 +32,8 @@ function newDashboard () {
APP_SCHEMA_ARRAY = getAppSchema()
for (let i = 0; i < APP_SCHEMA_ARRAY.length; i++) {
let nodeDefinition = APP_SCHEMA_ARRAY[i]
let key
if (nodeDefinition.subType !== undefined) {
key = nodeDefinition.type + '-' + nodeDefinition.subType
} else {
key = nodeDefinition.type
}
let key = nodeDefinition.type
APP_SCHEMA_MAP.set(key, nodeDefinition)
}
@@ -54,22 +45,16 @@ function newDashboard () {
if (canvas !== undefined) { canvas.finalize() }
/* Here we check where we are executing. In case we are Local we need to create a Local Dummy User and Team. */
/* Here we check where we are executing. In case we are Local we need to create a Local Dummy User and Data Mine. */
if (window.canvasApp.executingAt === 'Local') {
window.localStorage.setItem(LOGGED_IN_ACCESS_TOKEN_LOCAL_STORAGE_KEY, 'Local Access Token') // Dummy Access Token
window.localStorage.setItem(LOGGED_IN_USER_LOCAL_STORAGE_KEY, '{"authId":"x|x","alias":"user"}') // Dummy Local User
}
/* Here we will setup the global eventHandler that will enable the Canvas App to react to events happening outside its execution scope. */
/* Here we used to have a call to the DataMines Module to get the profile pictures. That was removed but to keep things working, we do this: */
window.canvasApp.eventHandler = newEventHandler()
userProfileChangedEventSubscriptionId = window.canvasApp.eventHandler.listenToEvent('User Profile Changed', userProfileChanged)
browserResizedEventSubscriptionId = window.canvasApp.eventHandler.listenToEvent('Browser Resized', browserResized)
/* Here we used to have a call to the Teams Module to get the profile pictures. That was removed but to keep things working, we do this: */
window.canvasApp.context.teamProfileImages = new Map()
window.canvasApp.context.dataMineProfileImages = new Map()
window.canvasApp.context.fbProfileImages = new Map()
setTimeout(delayedStart, DEBUG_START_UP_DELAY)
@@ -85,8 +70,8 @@ function newDashboard () {
let market = {
id: 2,
assetA: 'USDT',
assetB: 'BTC'
baseAsset: 'USDT',
quotedAsset: 'BTC'
}
markets = new Map()
@@ -100,31 +85,10 @@ function newDashboard () {
}
}
function userProfileChanged () {
try {
canvas.topSpace.initialize()
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] userProfileChanged -> err = ' + err.stack) }
}
}
function browserResized () {
try {
browserCanvas = document.getElementById('canvas')
browserCanvas.width = window.innerWidth
browserCanvas.height = window.innerHeight - CURRENT_TOP_MARGIN
viewPort.initialize()
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] browserResized -> err = ' + err.stack) }
}
}
function setBrowserEvents () {
window.onbeforeunload = onBrowserClosed
function onBrowserClosed () {
canvas.designerSpace.workspace.stopAllRunningTasks()
// canvas.designerSpace.workspace.stopAllRunningTasks()
}
}
}
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -23,20 +23,23 @@ function newNodeCloning () {
if (nodeDefinition !== undefined) {
let object = {
type: node.type,
subType: node.subType,
name: node.name,
code: node.code
}
/* Children Nodes */
if (nodeDefinition.properties !== undefined) {
let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoind counting each property of those as individual children.
for (let i = 0; i < nodeDefinition.properties.length; i++) {
let property = nodeDefinition.properties[i]
switch (property.type) {
case 'node': {
if (node[property.name] !== undefined) {
object[property.name] = cloneNode(node[property.name])
if (property.name !== previousPropertyName) {
if (node[property.name] !== undefined) {
object[property.name] = cloneNode(node[property.name])
}
previousPropertyName = property.name
}
break
}
@@ -72,20 +75,23 @@ function newNodeCloning () {
if (nodeDefinition !== undefined) {
let object = {
type: node.type,
subType: node.subType,
name: node.name,
code: node.code
}
/* Children Nodes */
if (nodeDefinition.properties !== undefined) {
let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoind counting each property of those as individual children.
for (let i = 0; i < nodeDefinition.properties.length; i++) {
let property = nodeDefinition.properties[i]
switch (property.type) {
case 'node': {
if (node[property.name] !== undefined) {
object[property.name] = redirectReferenceParents(node[property.name])
if (property.name !== previousPropertyName) {
if (node[property.name] !== undefined) {
object[property.name] = redirectReferenceParents(node[property.name])
}
previousPropertyName = property.name
}
break
}
@@ -139,7 +145,8 @@ function newNodeCloning () {
isPinned: node.payload.floatingObject.isPinned,
isFrozen: (node.payload.floatingObject.isFrozen && node.payload.floatingObject.frozenManually),
isCollapsed: (node.payload.floatingObject.isCollapsed && node.payload.floatingObject.collapsedManually),
isTensed: (node.payload.floatingObject.isTensed && node.payload.floatingObject.tensedManually)
angleToParent: (node.payload.floatingObject.angleToParent),
distanceToParent: (node.payload.floatingObject.distanceToParent)
},
uiObject: {
isRunning: node.payload.uiObject.isRunning,
@@ -151,7 +158,6 @@ function newNodeCloning () {
if (node.payload.referenceParent !== undefined) {
savedPayload.referenceParent = {
type: node.payload.referenceParent.type,
subType: node.payload.referenceParent.subType,
name: node.payload.referenceParent.name,
id: node.payload.referenceParent.id
}
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -30,32 +30,45 @@ function newSessionFunctions () {
let key = node.name + '-' + node.type + '-' + node.id
let thisNodeDefinition = node.payload.referenceParent
let lightingPath = '' +
'Trading System->' +
'Parameters->' +
'Base Asset->Time Range->Time Frame->Slippage->Fee Structure->' +
'Exchange Account Asset->Asset->' +
'Strategy->' +
'Trigger Stage->Trigger On Event->Trigger Off Event->Take Position Event->' +
'Announcement->Telegram Bot->' +
'Open Stage->Initial Definition->Open Execution->' +
'Position Size->Position Rate->Formula->' +
'Initial Stop->Initial Take Profit->' +
'Manage Stage->' +
'Stop->Take Profit->' +
'Phase->Formula->Next Phase Event->' +
'Situation->Condition->Javascript Code->' +
'Announcement->Telegram Bot->' +
'Close Stage->Close Execution->'
let tradingSystem = functionLibraryProtocolNode.getProtocolNode(node.payload.referenceParent, false, true, true, false, false, lightingPath)
lightingPath = '' +
'Backtesting Session->Paper Trading Session->Fordward Testing Session->Live Trading Session->' +
'Parameters->' +
'Base Asset->Time Range->Time Frame->Slippage->Fee Structure->' +
'Exchange Account Asset->Asset->'
let session = functionLibraryProtocolNode.getProtocolNode(node, false, true, true, false, false, lightingPath)
/* Raise event to run the session */
let event = {
session: JSON.stringify(functionLibraryProtocolNode.getProtocolNode(node, false, true, true)),
definition: JSON.stringify(functionLibraryProtocolNode.getProtocolNode(thisNodeDefinition, false, true, true)),
uiCurrentValues: getUICurrentValues()
session: JSON.stringify(session),
tradingSystem: JSON.stringify(tradingSystem)
}
systemEventHandler.raiseEvent(key, 'Run Session', event)
function getUICurrentValues () {
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 uiCurrentValues = {
initialDatetime: dateAtScreenCorner,
timePeriod: timePeriod,
timestamp: (new Date()).valueOf()
}
return uiCurrentValues
if (node.payload.parentNode.payload.parentNode.payload.parentNode.payload.parentNode === undefined) {
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
return
}
}
File diff suppressed because it is too large. Load diff
@@ -24,10 +24,42 @@ function newTaskFunctions () {
process.payload.uiObject.run()
}
let lightingPath = '->Task->' +
'Sensor Bot Instance->' +
'Indicator Bot Instance->' +
'Trading Bot Instance->' +
'Sensor Process Instance->Indicator Process Instance->Trading Process Instance->' +
'Market Reference->' +
'Key Instance->Exchange Account Key->' +
'Market->Exchange Markets->Crypto Exchange->' +
'Market Base Asset->Market Quoted Asset->Asset->' +
'Backtesting Session->Live Trading Session->Paper Trading Session->Fordward Testing Session->' +
'Process Definition->' +
'Process Output->Output Dataset->Dataset Definition->Product Definition->' +
'Process Dependencies->' +
'Status Dependency->Status Report->Process Definition->' +
'Data Dependency->Dataset Definition->Product Definition->' +
'Record Definition->Record Property->Formula->' +
'Data Building Procedure->' +
'Procedure Initialization->Javascript Code->' +
'Procedure Loop->Javascript Code->' +
'Calculations Procedure->' +
'Procedure Initialization->Javascript Code->' +
'Procedure Loop->Javascript Code->' +
'Status Report->' +
'Execution Finished Event->' +
'Execution Started Event->Execution Finished Event->Process Definition->' +
'Sensor Bot->' +
'Indicator Bot->' +
'Trading Bot->' +
'Data Mine->'
let definition = functionLibraryProtocolNode.getProtocolNode(node, false, true, true, false, false, lightingPath)
let event = {
taskId: node.id,
taskName: node.name,
definition: JSON.stringify(functionLibraryProtocolNode.getProtocolNode(node, false, true, true, false, false, true, true)) // <- We need to do this workaround in order no to send unescaped charactars to the taskManager.
definition: JSON.stringify(definition) // <- We need to do this workaround in order no to send unescaped charactars to the taskManager.
}
if (node.payload.parentNode === undefined) {
File diff suppressed because it is too large. Load diff
+9 -628
View File
@@ -13,7 +13,6 @@ function newWorkspace () {
nodeChildren: undefined,
getNodeThatIsOnFocus: getNodeThatIsOnFocus,
getNodeByShortcutKey: getNodeByShortcutKey,
getAllTradingBotInstances: getAllTradingBotInstances,
stopAllRunningTasks: stopAllRunningTasks,
onMenuItemClick: onMenuItemClick,
physics: physics,
@@ -133,19 +132,17 @@ function newWorkspace () {
workingAtTask++
break
case 4:
functionLibraryUiObjectsFromNodes.recreateWorkspace(thisObject.workspaceNode)
functionLibraryUiObjectsFromNodes.recreateWorkspace(thisObject.workspaceNode, true)
workingAtTask++
break
case 5:
canvas.chartSpace.finalize()
canvas.chartSpace.reset()
workingAtTask++
break
case 6:
canvas.chartSpace.initialize()
workingAtTask = 0
circularProgressBar.visible = false
break
}
}
}
@@ -191,34 +188,6 @@ function newWorkspace () {
}
}
function getAllTradingBotInstances () {
let tradingBotInstances = []
for (let i = 0; i < thisObject.workspaceNode.rootNodes.length; i++) {
let rootNode = thisObject.workspaceNode.rootNodes[i]
if (rootNode.type === 'Network') {
if (rootNode.networkNodes !== undefined) {
for (let j = 0; j < rootNode.networkNodes.length; j++) {
let networkNode = rootNode.networkNodes[j]
for (let i = 0; i < networkNode.taskManagers.length; i++) {
let taskManager = networkNode.taskManagers[i]
for (let k = 0; k < taskManager.tasks.length; k++) {
let task = taskManager.tasks[k]
if (task.bot !== undefined) {
if (task.bot.type === 'Trading Bot Instance') {
if (task.bot.payload.floatingObject.isCollapsed !== true) {
tradingBotInstances.push(task.bot)
}
}
}
}
}
}
}
}
}
return tradingBotInstances
}
function getNodeByShortcutKey (searchingKey) {
for (let i = 0; i < thisObject.workspaceNode.rootNodes.length; i++) {
let rootNode = thisObject.workspaceNode.rootNodes[i]
@@ -256,8 +225,8 @@ function newWorkspace () {
/* It does not exist, so we recreeate it respecting the inner state of each object. */
let positionOffset = {
x: spawnPosition.x - droppedNode.savedPayload.targetPosition.x,
y: spawnPosition.y - droppedNode.savedPayload.targetPosition.y
x: spawnPosition.x - droppedNode.savedPayload.position.x,
y: spawnPosition.y - droppedNode.savedPayload.position.y
}
thisObject.workspaceNode.rootNodes.push(droppedNode)
@@ -277,6 +246,11 @@ function newWorkspace () {
functionLibraryUiObjectsFromNodes.addUIObject(payload.node, relatedUiObject)
}
break
case 'Add Missing Children':
{
functionLibraryUiObjectsFromNodes.addMissingChildren(payload.node)
}
break
case 'Delete UI Object':
{
functionLibraryNodeDeleter.deleteUIObject(payload.node, thisObject.workspaceNode.rootNodes)
@@ -374,599 +348,6 @@ function newWorkspace () {
functionLibrarySessionFunctions.stopSession(payload.node, functionLibraryProtocolNode, callBackFunction)
}
break
case 'Add Definition':
{
functionLibraryUiObjectsFromNodes.addDefinition(payload.node)
}
break
case 'Add Team':
{
functionLibraryUiObjectsFromNodes.addTeam(payload.node)
}
break
case 'Add Sensor Bot':
{
functionLibraryUiObjectsFromNodes.addSensorBot(payload.node)
}
break
case 'Add Indicator Bot':
{
functionLibraryUiObjectsFromNodes.addIndicatorBot(payload.node)
}
break
case 'Add Trading Bot':
{
functionLibraryUiObjectsFromNodes.addTradingBot(payload.node)
}
break
case 'Add Process Definition':
{
functionLibraryUiObjectsFromNodes.addProcessDefinition(payload.node)
}
break
case 'Add Missing Process Definition Items':
{
functionLibraryUiObjectsFromNodes.addMissingProcessDefinitionItems(payload.node)
}
break
case 'Add Missing Product Definition Items':
{
functionLibraryUiObjectsFromNodes.addMissingProductDefinitionItems(payload.node)
}
break
case 'Add Process Output':
{
functionLibraryUiObjectsFromNodes.addProcessOutput(payload.node)
}
break
case 'Add Process Dependencies':
{
functionLibraryUiObjectsFromNodes.addProcessDependencies(payload.node)
}
break
case 'Add Status Report':
{
functionLibraryUiObjectsFromNodes.addStatusReport(payload.node)
}
break
case 'Add Execution Started Event':
{
functionLibraryUiObjectsFromNodes.addExecutionStartedEvent(payload.node)
}
break
case 'Add Execution Finished Event':
{
functionLibraryUiObjectsFromNodes.addExecutionFinishedEvent(payload.node)
}
break
case 'Add Calculations Procedure':
{
functionLibraryUiObjectsFromNodes.addCalculationsProcedure(payload.node)
}
break
case 'Add Data Building Procedure':
{
functionLibraryUiObjectsFromNodes.addDataBuildingProcedure(payload.node)
}
break
case 'Add Procedure Initialization':
{
functionLibraryUiObjectsFromNodes.addProcedureInitialization(payload.node)
}
break
case 'Add Procedure Loop':
{
functionLibraryUiObjectsFromNodes.addProcedureLoop(payload.node)
}
break
case 'Add Output Dataset':
{
functionLibraryUiObjectsFromNodes.addOutputDataset(payload.node)
}
break
case 'Add Status Dependency':
{
functionLibraryUiObjectsFromNodes.addStatusDependency(payload.node)
}
break
case 'Add Data Dependency':
{
functionLibraryUiObjectsFromNodes.addDataDependency(payload.node)
}
break
case 'Add Product Definition':
{
functionLibraryUiObjectsFromNodes.addProductDefinition(payload.node)
}
break
case 'Add Record Definition':
{
functionLibraryUiObjectsFromNodes.addRecordDefinition(payload.node)
}
break
case 'Add Record Property':
{
functionLibraryUiObjectsFromNodes.addRecordProperty(payload.node)
}
break
case 'Add Dataset Definition':
{
functionLibraryUiObjectsFromNodes.addDatasetDefinition(payload.node)
}
break
case 'Add Plotter':
{
functionLibraryUiObjectsFromNodes.addPlotter(payload.node)
}
break
case 'Add Plotter Module':
{
functionLibraryUiObjectsFromNodes.addPlotterModule(payload.node)
}
break
case 'Add Network':
{
functionLibraryUiObjectsFromNodes.addNetwork(payload.node)
}
break
case 'Add Network Node':
{
functionLibraryUiObjectsFromNodes.addNetworkNode(payload.node)
}
break
case 'Add Social Bots':
{
functionLibraryUiObjectsFromNodes.addSocialBots(payload.node)
}
break
case 'Add Telegram Bot':
{
functionLibraryUiObjectsFromNodes.addTelegramBot(payload.node)
}
break
case 'Add Announcement':
{
functionLibraryUiObjectsFromNodes.addAnnouncement(payload.node)
}
break
case 'Add Layer Manager':
{
functionLibraryUiObjectsFromNodes.addLayerManager(payload.node)
}
break
case 'Add Layer':
{
functionLibraryUiObjectsFromNodes.addLayer(payload.node)
}
break
case 'Add Task Manager':
{
functionLibraryUiObjectsFromNodes.addTaskManager(payload.node)
}
break
case 'Add Task':
{
functionLibraryUiObjectsFromNodes.addTask(payload.node)
}
break
case 'Add Sensor Bot Instance':
{
functionLibraryUiObjectsFromNodes.addSensorBotInstance(payload.node)
}
break
case 'Add Indicator Bot Instance':
{
functionLibraryUiObjectsFromNodes.addIndicatorBotInstance(payload.node)
}
break
case 'Add Trading Bot Instance':
{
functionLibraryUiObjectsFromNodes.addTradingBotInstance(payload.node)
}
break
case 'Add Process Instance':
{
functionLibraryUiObjectsFromNodes.addProcessInstance(payload.node)
}
break
case 'Add Backtesting Session':
{
functionLibraryUiObjectsFromNodes.addBacktestingSession(payload.node)
}
break
case 'Add Live Trading Session':
{
functionLibraryUiObjectsFromNodes.addLiveTradingSession(payload.node)
}
break
case 'Add Fordward Testing Session':
{
functionLibraryUiObjectsFromNodes.addFordwardTestingSession(payload.node)
}
break
case 'Add Paper Trading Session':
{
functionLibraryUiObjectsFromNodes.addPaperTradingSession(payload.node)
}
break
case 'Add Strategy':
{
functionLibraryUiObjectsFromNodes.addStrategy(payload.node)
}
break
case 'Add Parameters':
{
functionLibraryUiObjectsFromNodes.addParameters(payload.node)
}
break
case 'Add Missing Parameters':
{
functionLibraryUiObjectsFromNodes.addMissingParameters(payload.node)
}
break
case 'Add Missing Stages':
{
functionLibraryUiObjectsFromNodes.addMissingStages(payload.node)
}
break
case 'Add Missing Events':
{
functionLibraryUiObjectsFromNodes.addMissingEvents(payload.node)
}
break
case 'Add Missing Items':
{
functionLibraryUiObjectsFromNodes.addMissingItems(payload.node)
}
break
case 'Add Initial Definition':
{
functionLibraryUiObjectsFromNodes.addInitialDefinition(payload.node)
}
break
case 'Add Open Execution':
{
functionLibraryUiObjectsFromNodes.addOpenExecution(payload.node)
}
break
case 'Add Close Execution':
{
functionLibraryUiObjectsFromNodes.addCloseExecution(payload.node)
}
break
case 'Add Phase':
{
functionLibraryUiObjectsFromNodes.addPhase(payload.node)
}
break
case 'Add Formula':
{
functionLibraryUiObjectsFromNodes.addFormula(payload.node)
}
break
case 'Add Next Phase Event':
{
functionLibraryUiObjectsFromNodes.addNextPhaseEvent(payload.node)
}
break
case 'Add Situation':
{
functionLibraryUiObjectsFromNodes.addSituation(payload.node)
}
break
case 'Add Condition':
{
functionLibraryUiObjectsFromNodes.addCondition(payload.node)
}
break
case 'Add Code':
{
functionLibraryUiObjectsFromNodes.addJavascriptCode(payload.node)
}
break
case 'Add Exchange Account':
{
functionLibraryUiObjectsFromNodes.addExchangeAccount(payload.node)
}
break
case 'Add Exchange Account Asset':
{
functionLibraryUiObjectsFromNodes.addExchangeAccountAsset(payload.node)
}
break
case 'Add Exchange Account Key':
{
functionLibraryUiObjectsFromNodes.addExchangeAccountKey(payload.node)
}
break
case 'Add Trading System':
{
functionLibraryUiObjectsFromNodes.addTradingSystem(payload.node)
}
break
case 'Add Personal Data':
{
functionLibraryUiObjectsFromNodes.addPersonalData(payload.node)
}
break
case 'Delete Team': {
functionLibraryNodeDeleter.deleteTeam(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Sensor Bot': {
functionLibraryNodeDeleter.deleteSensorBot(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Indicator Bot': {
functionLibraryNodeDeleter.deleteIndicatorBot(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Trading Bot': {
functionLibraryNodeDeleter.deleteTradingBot(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Process Definition': {
functionLibraryNodeDeleter.deleteProcessDefinition(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Process Output': {
functionLibraryNodeDeleter.deleteProcessOutput(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Process Dependencies': {
functionLibraryNodeDeleter.deleteProcessDependencies(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Status Report': {
functionLibraryNodeDeleter.deleteStatusReport(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Execution Started Event': {
functionLibraryNodeDeleter.deleteExecutionStartedEvent(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Execution Finished Event': {
functionLibraryNodeDeleter.deleteExecutionFinishedEvent(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Calculations Procedure': {
functionLibraryNodeDeleter.deleteCalculationsProcedure(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Data Building Procedure': {
functionLibraryNodeDeleter.deleteDataBuildingProcedure(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Procedure Initialization': {
functionLibraryNodeDeleter.deleteProcedureInitialization(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Procedure Loop': {
functionLibraryNodeDeleter.deleteProcedureLoop(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Output Dataset': {
functionLibraryNodeDeleter.deleteOutputDataset(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Status Dependency': {
functionLibraryNodeDeleter.deleteStatusDependency(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Data Dependency': {
functionLibraryNodeDeleter.deleteDataDependency(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Product Definition': {
functionLibraryNodeDeleter.deleteProductDefinition(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Record Definition': {
functionLibraryNodeDeleter.deleteRecordDefinition(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Record Property': {
functionLibraryNodeDeleter.deleteRecordProperty(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Dataset Definition': {
functionLibraryNodeDeleter.deleteDatasetDefinition(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Plotter': {
functionLibraryNodeDeleter.deletePlotter(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Plotter Module': {
functionLibraryNodeDeleter.deletePlotterModule(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Network': {
functionLibraryNodeDeleter.deleteNetwork(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Network Node': {
functionLibraryNodeDeleter.deleteNetworkNode(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Social Bots': {
functionLibraryNodeDeleter.deleteSocialBots(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Social Bot': {
functionLibraryNodeDeleter.deleteSocialBot(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Announcement': {
functionLibraryNodeDeleter.deleteAnnouncement(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Layer Manager': {
functionLibraryNodeDeleter.deleteLayerManager(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Layer': {
functionLibraryNodeDeleter.deleteLayer(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Task Manager': {
functionLibraryNodeDeleter.deleteTaskManager(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Task': {
functionLibraryNodeDeleter.deleteTask(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Sensor Bot Instance': {
functionLibraryNodeDeleter.deleteSensorBotInstance(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Indicator Bot Instance': {
functionLibraryNodeDeleter.deleteIndicatorBotInstance(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Trading Bot Instance': {
functionLibraryNodeDeleter.deleteTradingBotInstance(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Process Instance': {
functionLibraryNodeDeleter.deleteProcessInstance(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Backtesting Session': {
functionLibraryNodeDeleter.deleteBacktestingSession(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Live Trading Session': {
functionLibraryNodeDeleter.deleteLiveTradingSession(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Fordward Testing Session': {
functionLibraryNodeDeleter.deleteFordwardTestingSession(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Paper Trading Session': {
functionLibraryNodeDeleter.deletePaperTradingSession(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Trading System': {
functionLibraryNodeDeleter.deleteTradingSystem(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Parameters': {
functionLibraryNodeDeleter.deleteParameters(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Base Asset': {
functionLibraryNodeDeleter.deleteBaseAsset(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Time Range': {
functionLibraryNodeDeleter.deleteTimeRange(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Time Period': {
functionLibraryNodeDeleter.deleteTimePeriod(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Slippage': {
functionLibraryNodeDeleter.deleteSlippage(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Fee Structure': {
functionLibraryNodeDeleter.deleteFeeStructure(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Strategy': {
functionLibraryNodeDeleter.deleteStrategy(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Trigger Stage': {
functionLibraryNodeDeleter.deleteTriggerStage(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Open Stage': {
functionLibraryNodeDeleter.deleteOpenStage(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Manage Stage': {
functionLibraryNodeDeleter.deleteManageStage(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Close Stage': {
functionLibraryNodeDeleter.deleteCloseStage(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Position Size': {
functionLibraryNodeDeleter.deletePositionSize(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Position Rate': {
functionLibraryNodeDeleter.deletePositionSize(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Initial Definition': {
functionLibraryNodeDeleter.deleteInitialDefinition(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Open Execution': {
functionLibraryNodeDeleter.deleteOpenExecution(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Close Execution': {
functionLibraryNodeDeleter.deleteCloseExecution(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Event': {
functionLibraryNodeDeleter.deleteEvent(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Managed Item': {
functionLibraryNodeDeleter.deleteManagedItem(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Phase': {
functionLibraryNodeDeleter.deletePhase(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Formula': {
functionLibraryNodeDeleter.deleteFormula(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Situation': {
functionLibraryNodeDeleter.deleteSituation(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Condition': {
functionLibraryNodeDeleter.deleteCondition(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Code': {
functionLibraryNodeDeleter.deleteJavascriptCode(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Exchange Account': {
functionLibraryNodeDeleter.deleteExchangeAccount(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Exchange Account Asset': {
functionLibraryNodeDeleter.deleteExchangeAccountAsset(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Exchange Account Key': {
functionLibraryNodeDeleter.deleteExchangeAccountKey(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Personal Data': {
functionLibraryNodeDeleter.deletePersonalData(payload.node, thisObject.workspaceNode.rootNodes)
break
}
case 'Delete Definition': {
functionLibraryNodeDeleter.deleteDefinition(payload.node, thisObject.workspaceNode.rootNodes)
break
}
default:
}
}
}
-64
View File
@@ -1,64 +0,0 @@

/*
We call displacement to the offset we can produce to the object which the displcement object is is a child from.
The displacement is a vector that displaces everything static drawn on on the context of the parent object.
*/
function newDisplacement () {
let displacement = {
containerName: '', // This is for debugging purposes only.
parentDisplacement: undefined, // Here we store the displacement object of the parent cointainer, if exists.
container: undefined,
x: 0, // This is the actual x displacement.
y: 0, // This is the actual y displacement.
displace: displace,
undisplaceThisPoint: undisplaceThisPoint,
displaceThisPoint: displaceThisPoint
}
return displacement
function displace (amountX, amountY) {
/* First we check if by allowing this displacement we would produce the current frame to be beyond its limit. */
tempDisplacement = newDisplacement()
tempDisplacement.x = amountX
tempDisplacement.y = amountY
if (this.container.frame.canYouMoveHere(tempDisplacement)) {
/* Now we displace */
displacement.x = displacement.x + amountX
displacement.y = displacement.y + amountY
return true
}
return false
}
function displaceThisPoint (point) {
if (this.parentDisplacement !== undefined) {
point = this.parentDisplacement.displaceThisPoint(point)
}
point.x = point.x + displacement.x
point.y = point.y + displacement.y
return point
}
function undisplaceThisPoint (point) {
if (this.parentDisplacement !== undefined) {
point = this.parentDisplacement.undisplaceThisPoint(point)
}
point.x = point.x - displacement.x
point.y = point.y - displacement.y
return point
}
}
+28 -14
View File
@@ -48,7 +48,8 @@ function newCircularMenu () {
/* Create the array of Menu Items */
let iconAndTextArray = []
let iconOnlyArray = []
let iconOnlyArray
let ringsArray = [[], [], []]
for (let i = 0; i < menuItemsInitialValues.length; i++) {
let menuItem = newCircularMenuItem()
@@ -81,9 +82,16 @@ function newCircularMenu () {
menuItem.confirmationLabel = menuItemInitialValue.confirmationLabel
menuItem.disableIfPropertyIsDefined = menuItemInitialValue.disableIfPropertyIsDefined
menuItem.propertyToCheckFor = menuItemInitialValue.propertyToCheckFor
menuItem.ring = menuItemInitialValue.ring
menuItem.icons = menuItemInitialValue.icons
if (menuItem.label === undefined) {
menuItem.type = 'Icon Only'
if (menuItem.ring === undefined) {
menutItem.ring = 1
}
iconOnlyArray = ringsArray[menuItem.ring - 1]
iconOnlyArray.push(menuItem)
} else {
menuItem.type = 'Icon & Text'
@@ -95,22 +103,28 @@ function newCircularMenu () {
menuItems.push(menuItem)
}
/* Here we calculate the angles for each menu item, and then apply it if it was not previously defined. */
let amplitud = 100
let initialAngle = 230
let step = amplitud / (iconOnlyArray.length - 1)
/* There are 3 possible rings of icons, we will go through each of them here. */
let amplitudeArray = [80, 50, 40]
let initialAngleArray = [220, 205, 200]
for (let j = 1; j < 4; j++) {
let iconOnlyArray = ringsArray[j - 1]
/* Here we calculate the angles for each menu item, and then apply it if it was not previously defined. */
let amplitude = amplitudeArray[j - 1]
let initialAngle = initialAngleArray[j - 1]
let step = amplitude / (iconOnlyArray.length - 1)
for (let i = 0; i < iconOnlyArray.length; i++) {
let menuItem = iconOnlyArray[i]
let angle = initialAngle - step * i
if (menuItem.angle === undefined) {
menuItem.angle = angle
for (let i = 0; i < iconOnlyArray.length; i++) {
let menuItem = iconOnlyArray[i]
let angle = initialAngle - step * i
if (menuItem.angle === undefined) {
menuItem.angle = angle
}
}
}
amplitud = 140
initialAngle = -70
step = amplitud / 7
/* Text and Icon */
let amplitude = 140
let initialAngle = -70
step = amplitude / 7
let currentItem = (7 - iconAndTextArray.length) / 2 + 1
for (let i = 0; i < iconAndTextArray.length; i++) {
let menuItem = iconAndTextArray[i]
+31 -11
View File
@@ -9,6 +9,7 @@ function newCircularMenuItem () {
confirmationLabel: undefined,
iconOn: undefined,
iconOff: undefined,
icons: undefined,
currentIcon: undefined,
disableIfPropertyIsDefined: undefined,
propertyToCheckFor: undefined,
@@ -92,6 +93,7 @@ function newCircularMenuItem () {
thisObject.container = undefined
thisObject.iconOn = undefined
thisObject.iconOff = undefined
thisObject.icons = undefined
thisObject.currentIcon = undefined
thisObject.payload = undefined
thisObject.actionFunction = undefined
@@ -110,7 +112,7 @@ function newCircularMenuItem () {
selfMouseNotOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver)
if (thisObject.type === 'Icon & Text') {
thisObject.container.frame.width = 185
thisObject.container.frame.width = 150
} else {
thisObject.container.frame.width = 50
}
@@ -144,15 +146,28 @@ function newCircularMenuItem () {
}
}
let radiousGrowthFactor
let radiusGrowthFactor
if (thisObject.type === 'Icon Only') {
radiousGrowthFactor = 5
switch (thisObject.ring) {
case 1: {
radiusGrowthFactor = 5
break
}
case 2: {
radiusGrowthFactor = 3.5
break
}
case 3: {
radiusGrowthFactor = 2
break
}
}
} else {
radiousGrowthFactor = 4
radiusGrowthFactor = 4
}
thisObject.container.frame.position.x = thisObject.container.frame.radius * radiousGrowthFactor / 7 * Math.cos(toRadians(thisObject.angle)) - thisObject.currentRadius * 1.5
thisObject.container.frame.position.y = thisObject.container.frame.radius * radiousGrowthFactor / 7 * Math.sin(toRadians(thisObject.angle)) - thisObject.container.frame.height / 2
thisObject.container.frame.position.x = thisObject.container.frame.radius * radiusGrowthFactor / 7 * Math.cos(toRadians(thisObject.angle)) - thisObject.currentRadius * 1.5
thisObject.container.frame.position.y = thisObject.container.frame.radius * radiusGrowthFactor / 7 * Math.sin(toRadians(thisObject.angle)) - thisObject.container.frame.height / 2
/* Temporary Status impacts on the label to use and the background of that label */
if (temporaryStatusCounter > 0) {
@@ -195,8 +210,13 @@ function newCircularMenuItem () {
thisObject.iconOn = canvas.designerSpace.iconByUiObjectType.get(thisObject.relatedUiObject)
thisObject.iconOff = canvas.designerSpace.iconByUiObjectType.get(thisObject.relatedUiObject)
} else {
thisObject.iconOn = canvas.designerSpace.iconCollection.get(thisObject.iconPathOn)
thisObject.iconOff = canvas.designerSpace.iconCollection.get(thisObject.iconPathOff)
if (thisObject.iconPathOn !== undefined && thisObject.iconPathOff !== undefined) {
thisObject.iconOn = canvas.designerSpace.iconCollection.get(thisObject.iconPathOn)
thisObject.iconOff = canvas.designerSpace.iconCollection.get(thisObject.iconPathOff)
} else {
thisObject.iconOn = canvas.designerSpace.iconCollection.get(thisObject.icons[thisObject.actionStatus()])
thisObject.iconOff = canvas.designerSpace.iconCollection.get(thisObject.icons[thisObject.actionStatus()])
}
}
}
@@ -300,7 +320,7 @@ function newCircularMenuItem () {
}
} else {
if (thisObject.workFailedLabel != undefined) {
setStatus(thisObject.workFailedLabel, UI_COLOR.TITANIUM_YELLOW, 500, STATUS_PRIMARY_WORK_FAILED)
setStatus(thisObject.workFailedLabel, UI_COLOR.TITANIUM_YELLOW, 250, STATUS_PRIMARY_WORK_FAILED)
}
}
} else {
@@ -311,7 +331,7 @@ function newCircularMenuItem () {
}
} else {
if (thisObject.workFailedLabel != undefined) {
setStatus(thisObject.workFailedLabel, UI_COLOR.TITANIUM_YELLOW, 500, STATUS_PRIMARY_WORK_FAILED)
setStatus(thisObject.workFailedLabel, UI_COLOR.TITANIUM_YELLOW, 250, STATUS_PRIMARY_WORK_FAILED)
}
}
}
@@ -323,7 +343,7 @@ function newCircularMenuItem () {
}
} else {
if (thisObject.secondaryWorkFailedLabel != undefined) {
setStatus(thisObject.secondaryWorkFailedLabel, UI_COLOR.TITANIUM_YELLOW, 500, STATUS_SECONDARY_WORK_FAILED)
setStatus(thisObject.secondaryWorkFailedLabel, UI_COLOR.TITANIUM_YELLOW, 250, STATUS_SECONDARY_WORK_FAILED)
}
}
}
+8 -6
View File
@@ -23,13 +23,13 @@ function newCircularProgressBar () {
let opacityCounters = []
let eventSubscriptionHeartbeat
let eventSubscriptionIdHeartbeat
return thisObject
function finalize () {
let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id
systemEventHandler.stopListening(key, eventSubscriptionHeartbeat)
systemEventHandler.stopListening(key, eventSubscriptionIdHeartbeat)
thisObject.container = undefined
thisObject.payload = undefined
@@ -52,6 +52,8 @@ function newCircularProgressBar () {
}
function onHeartBeat (message) {
if (thisObject.payload === undefined) { return }
if (thisObject.payload.uiObject === undefined) { return }
opacityCounters[message.event.seconds] = 2000
thisObject.payload.uiObject.setValue(message.event.processingDate)
}
@@ -76,11 +78,11 @@ function newCircularProgressBar () {
}
}
function drawBackground (pFloatingObject) {
function drawForeground (pFloatingObject) {
}
function drawForeground (pFloatingObject) {
function drawBackground (pFloatingObject) {
const VISIBLE_RADIUS = thisObject.container.frame.radius * 2
let visiblePosition = {
@@ -104,12 +106,12 @@ function newCircularProgressBar () {
browserCanvasContext.closePath()
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.GOLDEN_ORANGE + ', ' + OPACITY * 2 + ')'
browserCanvasContext.lineWidth = 6 + opacityCounters[i] / 100
browserCanvasContext.lineWidth = 6 + opacityCounters[i] / 100 / 2
browserCanvasContext.setLineDash([3, 4])
browserCanvasContext.stroke()
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.DARK_TURQUOISE + ', ' + OPACITY + ')'
browserCanvasContext.lineWidth = 0 + opacityCounters[i] / 100
browserCanvasContext.lineWidth = 0 + opacityCounters[i] / 100 / 2
browserCanvasContext.setLineDash([3, 4])
browserCanvasContext.stroke()
}
+4 -3
View File
@@ -34,6 +34,7 @@ function newConfigEditor () {
thisObject.container.frame.position.y = 0
let isMouseOver = false
let SIZE_FACTOR = 0.6
return thisObject
@@ -135,8 +136,8 @@ function newConfigEditor () {
thisObject.container.frame.position.x = 0
thisObject.container.frame.position.y = 0
thisObject.container.frame.width = thisObject.container.frame.radius * 1.8 * 2
thisObject.container.frame.height = thisObject.container.frame.radius * 1 * 2
thisObject.container.frame.width = thisObject.container.frame.radius * 1.8 * SIZE_FACTOR
thisObject.container.frame.height = thisObject.container.frame.radius * 1 * SIZE_FACTOR
let textAreaPosition = {
x: 0 - thisObject.container.frame.width / 2,
@@ -168,7 +169,7 @@ function newConfigEditor () {
position = thisObject.container.frame.frameThisPoint(position)
let radius = thisObject.container.frame.radius * 2
let radius = thisObject.container.frame.radius * SIZE_FACTOR
if (radius > 0.5) {
browserCanvasContext.beginPath()
+2 -23
View File
@@ -263,7 +263,9 @@ function newFloatingLayer () {
for (let i = 0; i < visibleFloatingObjects.length; i++) {
let floatingObject = visibleFloatingObjects[i]
floatingObject.physics()
/* From here on, only if they are not too far. */
if (canvas.floatingSpace.isItFar(floatingObject.payload)) { continue }
if (floatingObject.positionLocked === false) {
@@ -286,18 +288,6 @@ function newFloatingLayer () {
}
switch (floatingObject.type) {
case 'Profile Ball': {
payload.targetPosition = floatingObject.payload.profile.position
payload.visible = floatingObject.payload.profile.visible
break
}
case 'Note': {
payload.targetPosition = floatingObject.payload.notes[floatingObject.payloadNoteIndex].position
payload.visible = floatingObject.payload.notes[floatingObject.payloadNoteIndex].visible
break
}
case 'UI Object': {
payload.targetPosition = floatingObject.payload.targetPosition
payload.visible = floatingObject.payload.visible
@@ -341,8 +331,6 @@ function newFloatingLayer () {
// We let the Floating Object animate the physics loops by itself.
checkBoundaries(floatingObject)
floatingObject.physics()
/* Collision Control */
for (let k = i + 1; k < visibleFloatingObjects.length; k++) {
@@ -559,15 +547,6 @@ function newFloatingLayer () {
}
switch (floatingObject2.type) {
case 'Profile Ball': {
payload.targetPosition = floatingObject2.payload.profile.position
break
}
case 'Note': {
payload.targetPosition = floatingObject2.payload.notes[floatingObject2.payloadNoteIndex].position
break
}
case 'UI Object': {
payload.targetPosition = floatingObject2.payload.targetPosition
break
+113 -28
View File
@@ -22,7 +22,8 @@ function newFloatingObject () {
targetRadius: 0, // This is the target radius of the floating object with zoom applied. It should be animated until reaching this value.
isPinned: false,
isFrozen: false,
isTensed: false,
angleToParent: ANGLE_TO_PARENT.RANGE_90,
distanceToParent: DISTANCE_TO_PARENT.PARENT_100X,
isCollapsed: false,
isParentCollapsed: false,
frozenManually: false,
@@ -30,13 +31,15 @@ function newFloatingObject () {
getPinStatus: getPinStatus,
getFreezeStatus: getFreezeStatus,
getCollapseStatus: getCollapseStatus,
getTensionStatus: getTensionStatus,
getAngleToParent: getAngleToParent,
getDistanceToParent: getDistanceToParent,
nearbyFloatingObjects: [],
setPosition: setPosition,
pinToggle: pinToggle,
freezeToggle: freezeToggle,
collapseToggle: collapseToggle,
tensionToggle: tensionToggle,
angleToParentToggle: angleToParentToggle,
distanceToParentToggle: distanceToParentToggle,
physics: physics,
initializeMass: initializeMass,
initializeRadius: initializeRadius,
@@ -138,8 +141,12 @@ function newFloatingObject () {
return thisObject.isCollapsed
}
function getTensionStatus () {
return thisObject.isTensed
function getAngleToParent () {
return thisObject.angleToParent
}
function getDistanceToParent () {
return thisObject.distanceToParent
}
function freezeToggle () {
@@ -164,32 +171,73 @@ function newFloatingObject () {
return thisObject.isCollapsed
}
function tensionToggle () {
if (thisObject.isTensed !== true) {
thisObject.isTensed = true
thisObject.tensedManually = true
} else {
thisObject.isTensed = false
thisObject.tensedManually = false
function angleToParentToggle () {
switch (thisObject.angleToParent) {
case ANGLE_TO_PARENT.NOT_FIXED:
thisObject.angleToParent = ANGLE_TO_PARENT.RANGE_360
break
case ANGLE_TO_PARENT.RANGE_360:
thisObject.angleToParent = ANGLE_TO_PARENT.RANGE_180
break
case ANGLE_TO_PARENT.RANGE_180:
thisObject.angleToParent = ANGLE_TO_PARENT.RANGE_90
break
case ANGLE_TO_PARENT.RANGE_90:
thisObject.angleToParent = ANGLE_TO_PARENT.RANGE_45
break
case ANGLE_TO_PARENT.RANGE_45:
thisObject.angleToParent = ANGLE_TO_PARENT.NOT_FIXED
break
}
return thisObject.isTensed
return thisObject.angleToParent
}
function distanceToParentToggle () {
switch (thisObject.distanceToParent) {
case DISTANCE_TO_PARENT.NOT_FIXED:
thisObject.distanceToParent = DISTANCE_TO_PARENT.PARENT_025X
break
case DISTANCE_TO_PARENT.PARENT_025X:
thisObject.distanceToParent = DISTANCE_TO_PARENT.PARENT_050X
break
case DISTANCE_TO_PARENT.PARENT_050X:
thisObject.distanceToParent = DISTANCE_TO_PARENT.PARENT_100X
break
case DISTANCE_TO_PARENT.PARENT_100X:
thisObject.distanceToParent = DISTANCE_TO_PARENT.PARENT_150X
break
case DISTANCE_TO_PARENT.PARENT_150X:
thisObject.distanceToParent = DISTANCE_TO_PARENT.PARENT_200X
break
case DISTANCE_TO_PARENT.PARENT_200X:
thisObject.distanceToParent = DISTANCE_TO_PARENT.NOT_FIXED
break
}
return thisObject.distanceToParent
}
function physics () {
collapsePhysics()
frozenPhysics()
/* From here on, only if they are not too far. */
if (canvas.floatingSpace.isItFar(thisObject.payload)) { return }
thisObjectPhysics()
thisObject.payload.uiObject.physics()
frozenPhysics()
tensionPhysics()
positionContraintsPhysics()
}
function frozenPhysics () {
if (thisObject.frozenManually !== false) { return }
if (thisObject.payload === undefined) { return }
let parent = thisObject.payload.chainParent
if (parent !== undefined && parent.payload !== undefined) {
thisObject.isFrozen = parent.payload.floatingObject.isFrozen
if (parent !== undefined) {
if (parent.payload !== undefined) {
if (parent.payload.floatingObject !== undefined) {
thisObject.isFrozen = parent.payload.floatingObject.isFrozen
}
}
}
}
@@ -205,20 +253,54 @@ function newFloatingObject () {
}
}
function tensionPhysics () {
/* Tension Effect */
if (thisObject.isTensed === true) {
function positionContraintsPhysics () {
if (thisObject.angleToParent !== ANGLE_TO_PARENT.NOT_FIXED && thisObject.isOnFocus !== true) {
let parent = thisObject.payload.chainParent
if (parent === undefined) { return }
if (parent.payload === undefined) { return }
if (parent.payload.position === undefined) { return }
let distanceToChainParent = Math.sqrt(Math.pow(parent.payload.position.x - thisObject.container.frame.position.x, 2) + Math.pow(parent.payload.position.y - thisObject.container.frame.position.y, 2)) // ... we calculate the distance ...
let distanceToParent = Math.sqrt(Math.pow(parent.payload.position.x - thisObject.container.frame.position.x, 2) + Math.pow(parent.payload.position.y - thisObject.container.frame.position.y, 2)) // ... we calculate the distance ...
let parentChildren = canvas.designerSpace.workspace.nodeChildren.childrenCount(parent, thisObject.payload.node)
let axisCount = parentChildren.childrenCount
let axisIndex = parentChildren.childIndex
let baseAngle = 0
let angleToParentAngle
if (parent.payload.distance !== undefined) {
switch (thisObject.distanceToParent) {
case DISTANCE_TO_PARENT.PARENT_025X:
distanceToParent = parent.payload.distance / 4
break
case DISTANCE_TO_PARENT.PARENT_050X:
distanceToParent = parent.payload.distance / 2
break
case DISTANCE_TO_PARENT.PARENT_100X:
distanceToParent = parent.payload.distance
break
case DISTANCE_TO_PARENT.PARENT_150X:
distanceToParent = parent.payload.distance * 1.5
break
case DISTANCE_TO_PARENT.PARENT_200X:
distanceToParent = parent.payload.distance * 2
break
}
}
switch (thisObject.angleToParent) {
case ANGLE_TO_PARENT.RANGE_360:
angleToParentAngle = 360
break
case ANGLE_TO_PARENT.RANGE_180:
angleToParentAngle = 180
break
case ANGLE_TO_PARENT.RANGE_90:
angleToParentAngle = 90
break
case ANGLE_TO_PARENT.RANGE_45:
angleToParentAngle = 45
break
}
if (axisIndex === undefined) {
axisCount = 1
@@ -238,18 +320,21 @@ function newFloatingObject () {
}
}
let angleStep = 360 / axisCount
let separatorAngle = (360 - angleToParentAngle) / 2
let angleStep = angleToParentAngle / axisCount
thisObject.payload.angle = baseAngle + (axisIndex - 1) * angleStep
thisObject.payload.angle = baseAngle + separatorAngle + (axisIndex - 1) * angleStep
if (thisObject.payload.angle >= 360) {
thisObject.payload.angle = thisObject.payload.angle - 360
}
if (distanceToChainParent > 2000) { return } // this is introduced to avoid edges cases when importing workspaces.
thisObject.payload.distance = distanceToParent
if (distanceToParent > 2000 || thisObject.isPinned === true) { return } // this is introduced to avoid edges cases when importing workspaces.
newPosition = {
x: parent.payload.position.x + distanceToChainParent * Math.cos(toRadians(thisObject.payload.angle)),
y: parent.payload.position.y + distanceToChainParent * Math.sin(toRadians(thisObject.payload.angle))
x: parent.payload.position.x + distanceToParent * Math.cos(toRadians(thisObject.payload.angle)),
y: parent.payload.position.y + distanceToParent * Math.sin(toRadians(thisObject.payload.angle))
}
if (isNaN(newPosition.x) === false) {
thisObject.container.frame.position.x = newPosition.x
@@ -330,6 +415,7 @@ function newFloatingObject () {
}
function removeFocus () {
if (thisObject.payload === undefined) { return }
if (thisObject.isOnFocus === true) {
thisObject.targetRadius = thisObject.rawRadius * 1
thisObject.targetImageSize = thisObject.rawImageSize * 1
@@ -478,4 +564,3 @@ function newFloatingObject () {
function updateRadius () {
}
}
-334
View File
@@ -1,334 +0,0 @@

function newNote () {
const MODULE_NAME = 'Note'
let thisObject = {
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 () {
thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver)
thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick)
thisObject.container.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver)
}
function getContainer (point) {
let container
if (thisObject.container.frame.isThisPointHere(point, true) === true) {
return thisObject.container
} else {
return undefined
}
}
function physics () {
}
function onMouseOver () {
}
function onMouseNotOver () {
}
function onMouseClick (event) {
pPoint = event.point
pFloatingObject = event.parent
}
function drawBackground (pFloatingObject) {
let point = {
x: pFloatingObject.payload.notes[pFloatingObject.payloadNoteIndex].position.x,
y: pFloatingObject.payload.notes[pFloatingObject.payloadNoteIndex].position.y
}
point = viewPort.fitIntoVisibleArea(point)
if (pFloatingObject.container.frame.radius > 1) {
/* Target Line */
browserCanvasContext.beginPath()
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])
browserCanvasContext.lineWidth = 1
browserCanvasContext.stroke()
browserCanvasContext.setLineDash([0, 0])
}
if (pFloatingObject.container.frame.radius > 0.5) {
/* Target Spot */
var radius = 1
browserCanvasContext.beginPath()
browserCanvasContext.arc(point.x, point.y, radius, 0, Math.PI * 2, true)
browserCanvasContext.closePath()
browserCanvasContext.fillStyle = 'rgba(30, 30, 30, 1)'
browserCanvasContext.fill()
}
}
function drawOnFocus () {
}
function drawMiddleground () {
}
function drawForeground (pFloatingObject) {
const BUBBLE_CORNERS_RADIUS = 5
const TITLE_BAR_HEIGHT = 14
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
let borderPoint3
let borderPoint4
let intialDisplace = {
x: pFloatingObject.container.frame.position.x - BUBBLE_WIDTH / 2,
y: pFloatingObject.container.frame.position.y - BUBBLE_HEIGHT / 2
}
if (pFloatingObject.container.frame.radius > 5) {
/* Rounded Background */
borderPoint1 = {
x: intialDisplace.x + BUBBLE_CORNERS_RADIUS,
y: intialDisplace.y + BUBBLE_CORNERS_RADIUS
}
borderPoint2 = {
x: intialDisplace.x + BUBBLE_WIDTH - BUBBLE_CORNERS_RADIUS,
y: intialDisplace.y + BUBBLE_CORNERS_RADIUS
}
borderPoint3 = {
x: intialDisplace.x + BUBBLE_WIDTH - BUBBLE_CORNERS_RADIUS,
y: intialDisplace.y + BUBBLE_HEIGHT - BUBBLE_CORNERS_RADIUS
}
borderPoint4 = {
x: intialDisplace.x + BUBBLE_CORNERS_RADIUS,
y: intialDisplace.y + +BUBBLE_HEIGHT - BUBBLE_CORNERS_RADIUS
}
titleBarPoint1 = {
x: intialDisplace.x + 0,
y: intialDisplace.y + TITLE_BAR_HEIGHT
}
titleBarPoint2 = {
x: intialDisplace.x + BUBBLE_WIDTH,
y: intialDisplace.y + TITLE_BAR_HEIGHT
}
/* We paint the panel background first */
browserCanvasContext.fillStyle = 'rgba(255, 249, 196, 0.75)'
browserCanvasContext.beginPath()
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()
browserCanvasContext.fill()
browserCanvasContext.lineWidth = 0.1
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.DARK + ', 0.75)'
browserCanvasContext.stroke()
/* We paint the title bar now */
browserCanvasContext.fillStyle = 'rgba(244, 224, 44, 0.75)'
browserCanvasContext.beginPath()
browserCanvasContext.moveTo(titleBarPoint1.x, titleBarPoint1.y)
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()
browserCanvasContext.fill()
browserCanvasContext.lineWidth = 0.1
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.RUSTED_RED + ', 0.75)'
browserCanvasContext.stroke()
}
if (pFloatingObject.container.frame.radius > 0.5) {
/* Image */
let imagePosition = {
x: pFloatingObject.container.frame.position.x,
y: pFloatingObject.container.frame.position.y + BUBBLE_HEIGHT / 2
}
if (pFloatingObject.payloadImageId !== undefined) {
let image = document.getElementById(pFloatingObject.payloadImageId)
if (image !== null) {
browserCanvasContext.drawImage(image, imagePosition.x - pFloatingObject.currentImageSize / 2, imagePosition.y - pFloatingObject.currentImageSize / 2, pFloatingObject.currentImageSize, pFloatingObject.currentImageSize)
}
}
/* Image Contourn */
browserCanvasContext.beginPath()
browserCanvasContext.arc(imagePosition.x, imagePosition.y, pFloatingObject.currentImageSize / 2, 0, Math.PI * 2, true)
browserCanvasContext.closePath()
browserCanvasContext.strokeStyle = 'rgba(30, 30, 30, 0.25)'
browserCanvasContext.lineWidth = 1
browserCanvasContext.stroke()
/* Labels */
if (pFloatingObject.container.frame.radius > 6) {
browserCanvasContext.strokeStyle = pFloatingObject.labelStrokeStyle
const SIZE_PERCENTAGE = Math.trunc(pFloatingObject.container.frame.radius / pFloatingObject.targetRadius * 100) / 100
let ALPHA
if (pFloatingObject.targetRadius > 0) {
ALPHA = 0.5 - (1 - SIZE_PERCENTAGE) * 5
} else {
// Object is dying...
ALPHA = Math.trunc((0.5 - (100 - pFloatingObject.container.frame.radius / 100)) * 100) / 100
if (ALPHA < 0) { ALPHA = 0 }
}
let labelPoint
let fontSize = 10
let label
/* print the title */
label = pFloatingObject.payload.notes[pFloatingObject.payloadNoteIndex].title
if (label !== undefined) {
if (SIZE_PERCENTAGE > 0.9) {
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
let xOffset = label.length / 2 * fontSize * FONT_ASPECT_RATIO
let yOffset = (TITLE_BAR_HEIGHT - fontSize) / 2 + 2
labelPoint = {
x: intialDisplace.x + BUBBLE_WIDTH / 2 - xOffset,
y: intialDisplace.y + TITLE_BAR_HEIGHT - yOffset
}
browserCanvasContext.fillStyle = 'rgba(30, 30, 30, ' + ALPHA + ')'
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y)
}
}
/* Message Body */
label = pFloatingObject.payload.notes[pFloatingObject.payloadNoteIndex].body
if (label !== undefined) {
const WORDS_PER_ROW = 5
const TOTAL_ROWS = 5
if (SIZE_PERCENTAGE > 0.9) {
let rawLabelArray = label.split(' ')
let labelArray = []
/* Lets check when words are to long we add an empty space to the same line so as to roll all other words forward. */
for (let i = 0; i < rawLabelArray.length; i++) {
let word = rawLabelArray[i]
labelArray.push(word)
if (word.length > 8) {
labelArray.push('')
}
if (word.length > 10) {
labelArray.push('')
}
}
/* Calculate each ROW */
let labelRows = []
for (let i = 0; i < TOTAL_ROWS; i++) {
let labelRow = ''
for (let j = 0; j < WORDS_PER_ROW; j++) {
let newWord = labelArray[j + i * WORDS_PER_ROW]
if (newWord !== undefined && newWord !== '') {
labelRow = labelRow + ' ' + newWord
}
}
if (labelRow !== '') {
labelRows.push(labelRow)
}
}
/* Now we plot each row. */
for (let i = 0; i < labelRows.length; i++) {
let labelRow = labelRows[i]
let startingPosition = {
x: pFloatingObject.container.frame.position.x,
y: pFloatingObject.container.frame.position.y - labelRows.length / 2 * (fontSize * FONT_ASPECT_RATIO + 10)
}
labelPoint = {
x: startingPosition.x - labelRow.length / 2 * fontSize * FONT_ASPECT_RATIO,
y: startingPosition.y + (i + 1) * (fontSize * FONT_ASPECT_RATIO + 10)
}
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
browserCanvasContext.fillStyle = 'rgba(60, 60, 60, ' + ALPHA + ')'
browserCanvasContext.fillText(labelRow, labelPoint.x, labelPoint.y)
}
}
}
}
}
}
}
-314
View File
@@ -1,314 +0,0 @@

function newNoteSets () {
/*
Different plotters will identify sets of notes whithin the data they are plotting. They will create with them arrays of Notes data.
On the other hand the floating space, and a floting layer in particular, manages Notes floating objects, which are visible entities
that floats on the screen. These entities are animated at a certain peace, and their life cycle differs from the life cycle of the
arrays of raw data plotters have.
The purpose of this module, is to provide a mechnism of syncronization between the raw data and the visible floating objects and a
data structure wheere to store these floating objects.
A NoteSet in this context is an array of Notes floating objects belonging to the same owner, which could be a certain bot for instance.
This module is capable of managing an array of NoteSets.
*/
const MODULE_NAME = 'Note Sets'
const INFO_LOG = false
const INFO_WARN = true
const ERROR_LOG = true
const logger = newWebDebugLog()
logger.fileName = MODULE_NAME
let thisObject = {
createNoteSet: createNoteSet,
destroyNoteSet: destroyNoteSet,
initialize: initialize,
finalize: finalize
}
let noteSets = []
let floatingLayer
return thisObject
function initialize (pFloatingLayer) {
floatingLayer = pFloatingLayer
}
function finalize () {
floatingLayer.finalize()
floatingLayer = undefined
}
function createNoteSet (pPayload, pEventHandler, callBackFunction) {
try {
/*
During the creating of a NoteSet, no floating objects are created yet. What we do here is to create the data structure which will allocate
the Notes floating objects, once we receive the array of notes raw data from the plotter. This array will come as an event raised by the
plotter everytime it's set of raw data changes. Remember that the plotter is not only filtering out notes based on how far they are from the
position the user gives to the viewport, but also, the plotter can be receiving actually new notes from its datasource.
*/
if (INFO_LOG === true) { logger.write('[INFO] createNoteSet -> Entering function.') }
let noteSet = {
imageId: pPayload.profile.imageId,
floatingNotes: [],
payload: pPayload,
handle: Math.floor((Math.random() * 10000000) + 1)
}
noteSets.push(noteSet)
pEventHandler.listenToEvent('Notes Changed', onNotesChanged, noteSets.length - 1)
callBackFunction(GLOBAL.CUSTOM_OK_RESPONSE, noteSet.handle)
function onNotesChanged (pNewNotes, pNoteSetIndex) {
try {
if (INFO_LOG === true) { logger.write('[INFO] createNoteSet -> onNotesChanged -> Entering function.') }
if (INFO_LOG === true) { logger.write('[INFO] createNoteSet -> onNotesChanged -> pNewNotes.length = ' + pNewNotes.length) }
if (INFO_LOG === true) { logger.write('[INFO] createNoteSet -> onNotesChanged -> pNoteSetIndex = ' + pNoteSetIndex) }
let noteSet = noteSets[pNoteSetIndex]
let found = false
let newFloatingNotes
/*
First we remove the old notes. This means that we are going to scan all the floating objects that we have, and see one by one if they
are still present on the raw data sent by the plotter. If it is not there, that means that the floating object must be discarded.
*/
if (INFO_LOG === true) { logger.write('[INFO] createNoteSet -> onNotesChanged -> Remove old Notes.') }
newFloatingNotes = [] // We will create a new array of Floating Notes as a result of this operation.
/*
Here we scan the curren array of floating objects. We use the date + rate to create a unique key for each one, in order to be able to
compare it with the raw data. You will notice that instead of deleting from the current array what we actually do is to add the ones
that are still at the raw data array to a new array, and not adding the ones that are not.
*/
for (let j = 0; j < noteSet.floatingNotes.length; j++) {
found = false
let floatingNote = noteSet.floatingNotes[j]
let floatingNoteKey = floatingNote.date.toString() + floatingNote.rate.toString()
if (INFO_LOG === true) { logger.write('[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> j = ' + j) }
let i
for (let i = 0; i < pNewNotes.length; i++) {
let plotterNote = pNewNotes[i]
let plotterNoteKey = plotterNote.date.toString() + plotterNote.rate.toString()
if (INFO_LOG === true) { logger.write('[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> i = ' + i) }
if (INFO_LOG === true) { logger.write('[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> floatingNoteKey = ' + floatingNoteKey) }
if (INFO_LOG === true) { logger.write('[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> plotterNoteKey = ' + plotterNoteKey) }
if (plotterNoteKey === floatingNoteKey) {
found = true
if (INFO_LOG === true) { logger.write('[INFO] createNoteSet -> onNotesChanged -> found = ' + found) }
break
}
}
if (INFO_LOG === true) { logger.write('[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> End of For i.') }
if (INFO_LOG === true) { logger.write('[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> found = ' + found) }
if (found === false) {
/*
Each time we identify a floatingObject that is not at the raw data anymore, we request the floatinglayer to kill it.
*/
floatingLayer.removeFloatingObject(floatingNote.floatingHandle)
} else {
newFloatingNotes.push(floatingNote)
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 -> Added to newFloatingNotes.') }
if (INFO_LOG === true) { logger.write('[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> newFloatingNotes.length = ' + newFloatingNotes.length) }
/*
We set a property at each floatingObject of which is the index of the note at the raw data array, so that it can later evaluate its position or its visibility.
*/
let floatingObject = floatingLayer.getFloatingObject(floatingNote.floatingHandle)
floatingObject.payloadNoteIndex = i
if (INFO_LOG === true) { logger.write('[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> floatingObject index updated.') }
if (INFO_LOG === true) { logger.write('[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> floatingObject.payloadNoteIndex = ' + i) }
}
}
/*
We replace the current array, with the new one that only contains the surviving floating objects, meaning the ones that are still at the raw data received.
*/
noteSet.floatingNotes = newFloatingNotes
if (INFO_LOG === true) { logger.write('[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> noteSet.floatingNotes.length = ' + noteSet.floatingNotes.length) }
/*
Second we add the new notes. There might be new notes at the raw data received that we didnt have before at the NodeSet array. To figure out which
ones are, we need to scan the raw data array and compare each element with the ones of the NodeSet array. Whenever we find one that is not there,
we add it.
*/
if (INFO_LOG === true) { logger.write('[INFO] createNoteSet -> onNotesChanged -> Add new Notes.') }
newFloatingNotes = [] // We will create a new array of Floating Notes as a result of this operation.
/*
We are using the date and rate as a unique key to identify each note. To prevent the cases of duplicate keys, we will check that at
least to consecutive records dont have the same key, and if they do, will ignore the second one.
*/
let lastPlotterKey = ''
for (let i = 0; i < pNewNotes.length; i++) {
found = false
let plotterNote = pNewNotes[i]
let plotterNoteKey = plotterNote.date.toString() + plotterNote.rate.toString()
let floatingNote
let floatingNoteKey
if (lastPlotterKey === plotterNoteKey) {
if (INFO_WARN === true) { logger.write('[WARN] createNoteSet -> onNotesChanged -> Add new Notes -> Duplicate record detected. Discarding it.') }
if (INFO_WARN === true) { logger.write('[WARN] createNoteSet -> onNotesChanged -> Add new Notes -> i = ' + i) }
continue
}
lastPlotterKey = plotterNoteKey
if (INFO_LOG === true) { logger.write('[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> i = ' + i) }
for (let j = 0; j < noteSet.floatingNotes.length; j++) {
floatingNote = noteSet.floatingNotes[j]
floatingNoteKey = floatingNote.date.toString() + floatingNote.rate.toString()
if (INFO_LOG === true) { logger.write('[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> j = ' + j) }
if (INFO_LOG === true) { logger.write('[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> floatingNoteKey = ' + floatingNoteKey) }
if (INFO_LOG === true) { logger.write('[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> plotterNoteKey = ' + plotterNoteKey) }
if (plotterNoteKey === floatingNoteKey) {
found = true
if (INFO_LOG === true) { logger.write('[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> found = ' + found) }
break
}
}
if (INFO_LOG === true) { logger.write('[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> End of For j.') }
if (INFO_LOG === true) { logger.write('[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> found = ' + found) }
if (found === false) {
/*
Before adding a new item to the array, we need to create a floatingObject of type Note. Once we set its basic parameters
we can it to our array and to the floating layer.
*/
let floatingObject = newFloatingObject()
floatingObject.initialize('Note', '', floatingLayer)
floatingObject.payload = noteSet.payload
floatingObject.payloadNoteIndex = i
floatingObject.payloadImageId = noteSet.imageId
floatingObject.friction = 0.995
floatingObject.initializeMass(200)
// let bodyText = pNewNotes[i].body;
let radius
/*
if (bodyText.length < 100) {
radius = 100;
} else {
radius = bodyText.length;
}
*/
radius = 50
floatingObject.initializeRadius(radius)
floatingObject.initializeImageSize(15)
floatingObject.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', 0.5)'
floatingObject.labelStrokeStyle = 'rgba(60, 60, 60, 0.50)'
floatingLayer.addFloatingObject(floatingObject)
if (INFO_LOG === true) { logger.write('[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> onInitialized -> New Note added to Layer.') }
plotterNote.floatingHandle = floatingObject.handle
if (INFO_LOG === true) { logger.write('[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> plotterNote.floatingHandle = ' + plotterNote.floatingHandle) }
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) }
} else {
newFloatingNotes.push(floatingNote)
if (INFO_LOG === true) { logger.write('[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> onInitialized -> Old Note Kept.') }
if (INFO_LOG === true) { logger.write('[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> onInitialized -> floatingNote.floatingHandle = ' + floatingNote.floatingHandle) }
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) }
let floatingObject = floatingLayer.getFloatingObject(floatingNote.floatingHandle)
floatingObject.payloadNoteIndex = i
if (INFO_LOG === true) { logger.write('[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> onInitialized -> floatingObject index updated.') }
if (INFO_LOG === true) { logger.write('[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> onInitialized -> floatingObject.payloadNoteIndex = ' + i) }
}
}
noteSet.floatingNotes = newFloatingNotes
if (INFO_LOG === true) { logger.write('[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> noteSet.floatingNotes.length = ' + noteSet.floatingNotes.length) }
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] createNoteSet -> onNotesChanged -> err = ' + err.stack) }
}
}
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] createNoteSet -> err = ' + err.stack) }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE)
}
}
function destroyNoteSet (pHandle) {
try {
/*
Usually when a bot is disabled by the end user, or the zoom level changes to one where the notes must not be seen, this method
to destroy an entire NoteSet is executed. What we do in this situation is to localize the NoteSet to be destroyed and we need to
kill, one by one the floating objects in it. Finally we remove this NoteSet item from the NoteSets array.
*/
if (INFO_LOG === true) { logger.write('[INFO] destroyNoteSet -> Entering function.') }
for (let i = 0; i < noteSets.length; i++) {
let noteSet = noteSets[i]
if (noteSet.handle === pHandle) {
for (let j = 0; j < noteSet.floatingNotes.length; j++) {
let floatingNote = noteSet.floatingNotes[j]
floatingLayer.removeFloatingObject(floatingNote.floatingHandle)
}
noteSets.splice(i, 1) // Delete item from array.
return
}
}
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] destroyNoteSet -> err = ' + err.stack) }
}
}
}
-336
View File
@@ -1,336 +0,0 @@
function newProfileBall () {
const MODULE_NAME = 'Profile Ball'
let thisObject = {
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,
iconPathOn: 'Images/menu.icon.on.1.gif',
iconPathOff: 'Images/menu.icon.off.1.gif',
rawRadius: 8,
targetRadius: 0,
currentRadius: 0,
angle: 60
}/*,
{
visible: false,
iconPathOn: "Images/menu.icon.on.2.gif",
iconPathOff: "Images/menu.icon.off.2.gif",
rawRadius: 8,
targetRadius: 0,
currentRadius: 0,
angle: 20 * 1
},
{
visible: false,
iconPathOn: "Images/menu.icon.on.3.gif",
iconPathOff: "Images/menu.icon.off.3.gif",
rawRadius: 8,
targetRadius: 0,
currentRadius: 0,
angle: -20
},
{
visible: false,
iconPathOn: "Images/menu.icon.on.4.gif",
iconPathOff: "Images/menu.icon.off.4.gif",
rawRadius: 8,
targetRadius: 0,
currentRadius: 0,
angle: -60
} */
]
return thisObject
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.iconPathOff
}
menuItem.iconOn.src = window.canvasApp.urlPrefix + menuItem.iconPathOn
menuItem.icon = menuItem.iconOn // The default value is ON.
}
thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver)
thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick)
thisObject.container.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver)
}
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++) {
let menuItem = ballStringMenu[i]
if (Math.abs(menuItem.currentRadius - menuItem.targetRadius) >= 0.5) {
if (menuItem.currentRadius < menuItem.targetRadius) {
menuItem.currentRadius = menuItem.currentRadius + 0.5
} else {
menuItem.currentRadius = menuItem.currentRadius - 0.5
}
}
}
}
function onMouseOver () {
for (let i = 0; i < ballStringMenu.length; i++) {
let menuItem = ballStringMenu[i]
menuItem.targetRadius = menuItem.rawRadius * 1.5
}
}
function onMouseNotOver () {
for (let i = 0; i < ballStringMenu.length; i++) {
let menuItem = ballStringMenu[i]
menuItem.targetRadius = menuItem.rawRadius * 0 - i * 5
}
}
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++) {
let menuItem = ballStringMenu[i]
if (menuItem.canDrawIcon === true && menuItem.currentRadius > 1) {
let position = {
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)
let distance = Math.sqrt(Math.pow(position.x - pPoint.x, 2) + Math.pow(position.y - pPoint.y, 2))
if (distance < menuItem.currentRadius) {
menuItemIndex = i
}
}
}
if (menuItemIndex !== undefined) {
switch (menuItemIndex) {
case 0: {
// This menu item is to turn ON / OFF the plotting of this bot.
if (pFloatingObject.payload.profile.plot === true) {
pFloatingObject.payload.profile.plot = false
let menuItem = ballStringMenu[0]
menuItem.icon = menuItem.iconOff
} else {
pFloatingObject.payload.profile.plot = true
let menuItem = ballStringMenu[0]
menuItem.icon = menuItem.iconOn
}
break
}
case 1: {
// This menu item is to turn ON the Debug Log pannel for the bot.
break
}
}
}
}
function drawBackground (pFloatingObject) {
let point = {
x: pFloatingObject.payload.targetPosition.x,
y: pFloatingObject.payload.targetPosition.y
}
point = viewPort.fitIntoVisibleArea(point)
if (pFloatingObject.container.frame.radius > 1) {
/* Target Line */
browserCanvasContext.beginPath()
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])
browserCanvasContext.lineWidth = 1
browserCanvasContext.stroke()
browserCanvasContext.setLineDash([0, 0])
}
if (pFloatingObject.container.frame.radius > 0.5) {
/* Target Spot */
var radius = 1
browserCanvasContext.beginPath()
browserCanvasContext.arc(point.x, point.y, radius, 0, Math.PI * 2, true)
browserCanvasContext.closePath()
browserCanvasContext.fillStyle = 'rgba(30, 30, 30, 1)'
browserCanvasContext.fill()
}
}
function drawOnFocus () {
}
function drawMiddleground () {
}
function drawForeground (pFloatingObject) {
if (pFloatingObject.container.frame.radius > 5) {
/* Contourn */
browserCanvasContext.beginPath()
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.container.frame.radius > 0.5) {
/* Main FloatingObject */
var alphaA
if (pFloatingObject.container.frame.radius < 3) {
alphaA = 1
} else {
alphaA = 0.75
}
alphaA = 0.75
browserCanvasContext.beginPath()
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
browserCanvasContext.fill()
}
/* Image */
if (pFloatingObject.payload.profile.imageId !== undefined) {
let image = pFloatingObject.payload.profile.botAvatar
if (image !== null && image !== undefined) {
browserCanvasContext.save()
browserCanvasContext.beginPath()
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.container.frame.position.x - pFloatingObject.currentImageSize / 2, pFloatingObject.container.frame.position.y - pFloatingObject.currentImageSize / 2, pFloatingObject.currentImageSize, pFloatingObject.currentImageSize)
browserCanvasContext.beginPath()
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()
}
}
/* StringBall Menu */
for (let i = 0; i < ballStringMenu.length; i++) {
let menuItem = ballStringMenu[i]
if (menuItem.canDrawIcon === true && menuItem.currentRadius > 1) {
let position = {
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)
}
}
/* Label Text */
if (pFloatingObject.container.frame.radius > 6) {
browserCanvasContext.strokeStyle = pFloatingObject.labelStrokeStyle
let labelPoint
let fontSize = pFloatingObject.currentFontSize
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
let label
label = pFloatingObject.payload.profile.subTitle
if (label !== undefined) {
labelPoint = {
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.PRIMARY
browserCanvasContext.fillStyle = pFloatingObject.labelStrokeStyle
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y)
}
label = pFloatingObject.payload.profile.title
if (label !== undefined) {
labelPoint = {
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.PRIMARY
browserCanvasContext.fillStyle = pFloatingObject.labelStrokeStyle
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y)
}
}
}
}
-62
View File
@@ -1,62 +0,0 @@
function newProfileBalls () {
const MODULE_NAME = 'Profile Balls'
const INFO_LOG = false
const ERROR_LOG = true
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.
*/
let thisObject = {
createNewProfileBall: createNewProfileBall,
destroyProfileBall: destroyProfileBall,
initialize: initialize,
finalize: finalize
}
let floatingLayer
return thisObject
function initialize (pFloatingLayer) {
floatingLayer = pFloatingLayer
}
function finalize () {
floatingLayer.finalize()
floatingLayer = undefined
}
function createNewProfileBall (pPayload, callBackFunction) {
let floatingObject = newFloatingObject()
floatingObject.initialize('Profile Ball', '', floatingLayer)
floatingObject.payload = pPayload
floatingObject.friction = 0.995
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)'
floatingLayer.addFloatingObject(floatingObject)
callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE, floatingObject.handle)
}
function destroyProfileBall (pFloatingObjectHandle) {
floatingLayer.removeFloatingObject(pFloatingObjectHandle)
}
}
+155 -461
View File
@@ -94,9 +94,16 @@ function newUiObject () {
let currentValue = 0
let rightDragging = false
let eventSubscriptionIdHeartbeat
let eventSubscriptionIdOnStopped
return thisObject
function finalize () {
let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id
systemEventHandler.stopListening(key, eventSubscriptionIdHeartbeat, 'UiObject')
systemEventHandler.stopListening(key, eventSubscriptionIdOnStopped, 'UiObject')
thisObject.container.eventHandler.stopListening(selfFocusEventSubscriptionId)
thisObject.container.eventHandler.stopListening(selfNotFocuskEventSubscriptionId)
thisObject.container.eventHandler.stopListening(selfDisplaceEventSubscriptionId)
@@ -189,8 +196,33 @@ function newUiObject () {
if (container !== undefined) { return container }
}
container = thisObject.uiObjectTitle.getContainer(point)
if (container !== undefined) { return container }
let getitle = true
if (thisObject.codeEditor !== undefined) {
if (thisObject.codeEditor.visible === true) {
getitle = false
}
}
if (thisObject.configEditor !== undefined) {
if (thisObject.configEditor.visible === true) {
getitle = false
}
}
if (thisObject.conditionEditor !== undefined) {
if (thisObject.conditionEditor.visible === true) {
getitle = false
}
}
if (thisObject.formulaEditor !== undefined) {
if (thisObject.formulaEditor.visible === true) {
getitle = false
}
}
if (getitle === true) {
container = thisObject.uiObjectTitle.getContainer(point)
if (container !== undefined) { return container }
}
container = thisObject.menu.getContainer(point)
if (container !== undefined) { return container }
@@ -227,8 +259,10 @@ function newUiObject () {
thisObject.payload.targetPosition.x = thisObject.payload.position.x,
thisObject.payload.targetPosition.y = thisObject.payload.position.y
} else {
thisObject.payload.targetPosition.x = thisObject.payload.chainParent.payload.position.x
thisObject.payload.targetPosition.y = thisObject.payload.chainParent.payload.position.y
if (thisObject.payload.chainParent.payload.position !== undefined) {
thisObject.payload.targetPosition.x = thisObject.payload.chainParent.payload.position.x
thisObject.payload.targetPosition.y = thisObject.payload.chainParent.payload.position.y
}
}
if (thisObject.circularProgressBar !== undefined) {
@@ -255,314 +289,18 @@ function newUiObject () {
let nearbyFloatingObjects = thisObject.payload.floatingObject.nearbyFloatingObjects
let compatibleTypes
let compatibleSubTypes
switch (thisObject.payload.node.type) {
case 'Sensor Bot':
compatibleTypes = '->' + 'Team' + '->'
compatibleSubTypes = undefined
break
case 'Indicator Bot':
compatibleTypes = '->' + 'Team' + '->'
compatibleSubTypes = undefined
break
case 'Trading Bot':
compatibleTypes = '->' + 'Team' + '->'
compatibleSubTypes = undefined
break
case 'Process Definition':
compatibleTypes = '->' + 'Sensor Bot' + '->' + 'Indicator Bot' + '->' + 'Trading Bot' + '->'
compatibleSubTypes = undefined
break
case 'Process Output':
compatibleTypes = '->' + 'Process Definition' + '->'
compatibleSubTypes = undefined
break
case 'Process Dependencies':
compatibleTypes = '->' + 'Process Definition' + '->'
compatibleSubTypes = undefined
break
case 'Status Report':
compatibleTypes = '->' + 'Process Definition' + '->'
compatibleSubTypes = undefined
break
case 'Execution Started Event':
compatibleTypes = '->' + 'Process Definition' + '->'
compatibleSubTypes = undefined
break
case 'Execution Finished Event':
compatibleTypes = '->' + 'Process Definition' + '->'
compatibleSubTypes = undefined
break
case 'Calculations Procedure':
compatibleTypes = '->' + 'Product Definition' + '->'
compatibleSubTypes = undefined
break
case 'Data Building Procedure':
compatibleTypes = '->' + 'Product Definition' + '->'
compatibleSubTypes = undefined
break
case 'Procedure Initialization':
compatibleTypes = '->' + 'Calculations Procedure' + '->' + 'Data Building Procedure' + '->'
compatibleSubTypes = undefined
break
case 'Procedure Loop':
compatibleTypes = '->' + 'Calculations Procedure' + '->' + 'Data Building Procedure' + '->'
compatibleSubTypes = undefined
break
case 'Output Dataset':
compatibleTypes = '->' + 'Process Output' + '->'
compatibleSubTypes = undefined
break
case 'Status Dependency':
compatibleTypes = '->' + 'Process Dependencies' + '->'
compatibleSubTypes = undefined
break
case 'Data Dependency':
compatibleTypes = '->' + 'Process Dependencies' + '->'
compatibleSubTypes = undefined
break
case 'Product Definition':
compatibleTypes = '->' + 'Sensor Bot' + '->' + 'Indicator Bot' + '->' + 'Trading Bot' + '->'
compatibleSubTypes = undefined
break
case 'Record Definition':
compatibleTypes = '->' + 'Product Definition' + '->'
compatibleSubTypes = undefined
break
case 'Record Property':
compatibleTypes = '->' + 'Record Definition' + '->'
compatibleSubTypes = undefined
break
case 'Dataset Definition':
compatibleTypes = '->' + 'Product Definition' + '->'
compatibleSubTypes = undefined
break
case 'Plotter':
compatibleTypes = '->' + 'Team' + '->'
compatibleSubTypes = undefined
break
case 'Plotter Module':
compatibleTypes = '->' + 'Plotter' + '->'
compatibleSubTypes = undefined
break
case 'Trading System':
compatibleTypes = '->' + 'Definition' + '->'
compatibleSubTypes = undefined
break
case 'Personal Data':
compatibleTypes = '->' + 'Definition' + '->'
compatibleSubTypes = undefined
break
case 'Network Node':
compatibleTypes = '->' + 'Network' + '->'
compatibleSubTypes = undefined
break
case 'Exchange Account':
compatibleTypes = '->' + 'Personal Data' + '->'
compatibleSubTypes = undefined
break
case 'Exchange Account Asset':
compatibleTypes = '->' + 'Exchange Account' + '->'
compatibleSubTypes = undefined
break
case 'Exchange Account Key':
compatibleTypes = '->' + 'Exchange Account' + '->' + 'Parameters' + '->'
compatibleSubTypes = undefined
break
case 'Parameters':
compatibleTypes = '->' + 'Trading System' + '->' + 'Backtesting Session' + '->' + 'Live Trading Session' + '->' + 'Paper Trading Session' + '->' + 'Fordward Testing Session' + '->'
compatibleSubTypes = '->' + 'Trading Process Instance' + '->'
break
case 'Backtesting Session':
compatibleTypes = '->' + 'Process Instance' + '->'
compatibleSubTypes = '->' + 'Trading Process Instance' + '->'
break
case 'Live Trading Session':
compatibleTypes = '->' + 'Process Instance' + '->'
compatibleSubTypes = '->' + 'Trading Process Instance' + '->'
break
case 'Paper Trading Session':
compatibleTypes = '->' + 'Process Instance' + '->'
compatibleSubTypes = '->' + 'Trading Process Instance' + '->'
break
case 'Fordward Testing Session':
compatibleTypes = '->' + 'Process Instance' + '->'
compatibleSubTypes = '->' + 'Trading Process Instance' + '->'
break
case 'Base Asset':
compatibleTypes = '->' + 'Parameters' + '->'
compatibleSubTypes = undefined
break
case 'Time Range':
compatibleTypes = '->' + 'Parameters' + '->'
compatibleSubTypes = undefined
break
case 'Time Period':
compatibleTypes = '->' + 'Parameters' + '->'
compatibleSubTypes = undefined
break
case 'Slippage':
compatibleTypes = '->' + 'Parameters' + '->'
compatibleSubTypes = undefined
break
case 'Fee Structure':
compatibleTypes = '->' + 'Parameters' + '->'
compatibleSubTypes = undefined
break
case 'Layer Manager':
compatibleTypes = '->' + 'Backtesting Session' + '->' + 'Live Trading Session' + '->' + 'Paper Trading Session' + '->' + 'Fordward Testing Session' + '->'
compatibleSubTypes = undefined
break
case 'Layer':
compatibleTypes = '->' + 'Layer Manager' + '->'
compatibleSubTypes = undefined
break
case 'Social Bots':
compatibleTypes = '->' + 'Backtesting Session' + '->' + 'Live Trading Session' + '->' + 'Paper Trading Session' + '->' + 'Fordward Testing Session' + '->'
compatibleSubTypes = undefined
break
case 'Telegram Bot':
compatibleTypes = '->' + 'Social Bots' + '->'
compatibleSubTypes = undefined
break
case 'Announcement':
compatibleTypes = '->' + 'Telegram Bot' + '->' + 'Trigger On Event' + '->' + 'Trigger Off Event' + '->' + 'Take Position Event' + '->' + 'Next Phase Event' + '->' + '->' + 'Phase' + '->'
compatibleSubTypes = undefined
break
case 'Task Manager':
compatibleTypes = '->' + 'Network Node' + '->'
compatibleSubTypes = undefined
break
case 'Task':
compatibleTypes = '->' + 'Task Manager' + '->'
compatibleSubTypes = undefined
break
case 'Sensor Bot Instance':
compatibleTypes = '->' + 'Task' + '->'
compatibleSubTypes = undefined
break
case 'Indicator Bot Instance':
compatibleTypes = '->' + 'Task' + '->'
compatibleSubTypes = undefined
break
case 'Trading Bot Instance':
compatibleTypes = '->' + 'Task' + '->'
compatibleSubTypes = undefined
break
case 'Process Instance':
switch (thisObject.payload.node.subType) {
case 'Sensor Process Instance': {
compatibleTypes = '->' + 'Sensor Bot Instance' + '->'
break
}
case 'Indicator Process Instance': {
compatibleTypes = '->' + 'Indicator Bot Instance' + '->'
break
}
case 'Trading Process Instance': {
compatibleTypes = '->' + 'Trading Bot Instance' + '->'
break
}
}
compatibleSubTypes = undefined
break
case 'Strategy':
compatibleTypes = '->' + 'Trading System' + '->'
compatibleSubTypes = undefined
break
case 'Trigger Stage':
compatibleTypes = '->' + 'Strategy' + '->'
compatibleSubTypes = undefined
break
case 'Open Stage':
compatibleTypes = '->' + 'Strategy' + '->'
compatibleSubTypes = undefined
break
case 'Manage Stage':
compatibleTypes = '->' + 'Strategy' + '->'
compatibleSubTypes = undefined
break
case 'Close Stage':
compatibleTypes = '->' + 'Strategy' + '->'
compatibleSubTypes = undefined
break
case 'Position Size':
compatibleTypes = '->' + 'Initial Definition' + '->'
compatibleSubTypes = undefined
break
case 'Position Rate':
compatibleTypes = '->' + 'Initial Definition' + '->'
compatibleSubTypes = undefined
break
case 'Take Position Event':
compatibleTypes = '->' + 'Trigger Stage' + '->'
compatibleSubTypes = undefined
break
case 'Trigger Off Event':
compatibleTypes = '->' + 'Trigger Stage' + '->'
compatibleSubTypes = undefined
break
case 'Trigger On Event':
compatibleTypes = '->' + 'Trigger Stage' + '->'
compatibleSubTypes = undefined
break
case 'Initial Definition':
compatibleTypes = '->' + 'Open Stage' + '->'
compatibleSubTypes = undefined
break
case 'Open Execution':
compatibleTypes = '->' + 'Open Stage' + '->'
compatibleSubTypes = undefined
break
case 'Close Execution':
compatibleTypes = '->' + 'Close Stage' + '->'
compatibleSubTypes = undefined
break
case 'Stop':
compatibleTypes = '->' + 'Manage Stage' + '->' + 'Initial Definition' + '->'
compatibleSubTypes = undefined
break
case 'Take Profit':
compatibleTypes = '->' + 'Manage Stage' + '->' + 'Initial Definition' + '->'
compatibleSubTypes = undefined
break
case 'Phase':
compatibleTypes = '->' + 'Stop' + '->' + 'Take Profit' + '->' + 'Phase' + '->'
compatibleSubTypes = undefined
break
case 'Formula':
compatibleTypes = '->' + 'Position Size' + '->' + 'Position Rate' + '->' + 'Phase' + '->' + 'Announcement' + '->' + 'Record Property' + '->'
compatibleSubTypes = undefined
break
case 'Next Phase Event':
compatibleTypes = '->' + 'Phase' + '->'
compatibleSubTypes = undefined
break
case 'Situation':
compatibleTypes = '->' + 'Take Position Event' + '->' + 'Trigger On Event' + '->' + 'Trigger Off Event' + '->' + 'Next Phase Event' + '->'
compatibleSubTypes = undefined
break
case 'Condition':
compatibleTypes = '->' + 'Situation' + '->'
compatibleSubTypes = undefined
break
case 'Javascript Code':
compatibleTypes = '->' + 'Condition' + '->' + 'Procedure Initialization' + '->' + 'Procedure Loop' + '->' + 'Plotter Module' + '->' + 'Plotter Panel' + '->'
compatibleSubTypes = undefined
break
default:
let nodeDefinition = APP_SCHEMA_MAP.get(thisObject.payload.node.type)
if (nodeDefinition !== undefined) {
if (nodeDefinition.chainAttachesTo !== undefined) {
compatibleTypes = nodeDefinition.chainAttachesTo.compatibleTypes
compatibleSubTypes = nodeDefinition.chainAttachesTo.compatibleSubTypes
} else {
return
}
} else {
return
}
let nodeDefinition = APP_SCHEMA_MAP.get(thisObject.payload.node.type)
if (nodeDefinition !== undefined) {
if (nodeDefinition.chainAttachesTo !== undefined) {
compatibleTypes = nodeDefinition.chainAttachesTo.compatibleTypes
} else {
return
}
} else {
return
}
let foundCompatible = false
chainAttachToNode = undefined
isChainAttaching = false
@@ -574,7 +312,7 @@ function newUiObject () {
let nearbyNode = floatingObject.payload.node
if (compatibleTypes.indexOf('->' + nearbyNode.type + '->') >= 0) {
/* Discard App Schema defined objects with busy coonection ports */
let nodeDefinition = APP_SCHEMA_MAP.get(thisObject.payload.node.type)
nodeDefinition = APP_SCHEMA_MAP.get(thisObject.payload.node.type)
if (nodeDefinition !== undefined) {
let mustContinue = false
let parentNodeDefinition = APP_SCHEMA_MAP.get(nearbyNode.type)
@@ -601,55 +339,7 @@ function newUiObject () {
}
if (mustContinue === true) { continue }
}
/* Discard legacy objects with busy coonection ports */
if (thisObject.payload.node.type === 'Status Report' && nearbyNode.statusReport !== undefined) { continue }
if (thisObject.payload.node.type === 'Execution Started Event' && nearbyNode.executionStartedEvent !== undefined) { continue }
if (thisObject.payload.node.type === 'Execution Finished Event' && nearbyNode.executionFinishedEvent !== undefined) { continue }
if (thisObject.payload.node.type === 'Calculations Procedure' && nearbyNode.calculations !== undefined) { continue }
if (thisObject.payload.node.type === 'Data Building Procedure' && nearbyNode.dataBuilding !== undefined) { continue }
if (thisObject.payload.node.type === 'Procedure Initialization' && nearbyNode.initialization !== undefined) { continue }
if (thisObject.payload.node.type === 'Procedure Loop' && nearbyNode.loop !== undefined) { continue }
if (thisObject.payload.node.type === 'Record Definition' && nearbyNode.record !== undefined) { continue }
if (thisObject.payload.node.type === 'Task' && nearbyNode.task !== undefined) { continue }
if (thisObject.payload.node.type === 'Sensor Bot Instance' && nearbyNode.bot !== undefined) { continue }
if (thisObject.payload.node.type === 'Indicator Bot Instance' && nearbyNode.bot !== undefined) { continue }
if (thisObject.payload.node.type === 'Trading Bot Instance' && nearbyNode.bot !== undefined) { continue }
if (thisObject.payload.node.type === 'Process Instance' && nearbyNode.process !== undefined) { continue }
if (thisObject.payload.node.type === 'Trading System' && nearbyNode.tradingSystem !== undefined) { continue }
if (thisObject.payload.node.type === 'Personal Data' && nearbyNode.personalData !== undefined) { continue }
if (thisObject.payload.node.type === 'Parameters' && nearbyNode.parameters !== undefined) { continue }
if (thisObject.payload.node.type === 'Backtesting Session' && nearbyNode.session !== undefined) { continue }
if (thisObject.payload.node.type === 'Live Trading Session' && nearbyNode.session !== undefined) { continue }
if (thisObject.payload.node.type === 'Fordward Testing Session' && nearbyNode.session !== undefined) { continue }
if (thisObject.payload.node.type === 'Paper Trading Session' && nearbyNode.session !== undefined) { continue }
if (thisObject.payload.node.type === 'Base Asset' && nearbyNode.baseAsset !== undefined) { continue }
if (thisObject.payload.node.type === 'Time Range' && nearbyNode.timeRange !== undefined) { continue }
if (thisObject.payload.node.type === 'Time Period' && nearbyNode.timePeriod !== undefined) { continue }
if (thisObject.payload.node.type === 'Slippage' && nearbyNode.slippage !== undefined) { continue }
if (thisObject.payload.node.type === 'Fee Structure' && nearbyNode.feeStructure !== undefined) { continue }
if (thisObject.payload.node.type === 'Trigger Stage' && nearbyNode.triggerStage !== undefined) { continue }
if (thisObject.payload.node.type === 'Open Stage' && nearbyNode.openStage !== undefined) { continue }
if (thisObject.payload.node.type === 'Manage Stage' && nearbyNode.manageStage !== undefined) { continue }
if (thisObject.payload.node.type === 'Close Stage' && nearbyNode.closeStage !== undefined) { continue }
if (thisObject.payload.node.type === 'Position Size' && nearbyNode.positionSize !== undefined) { continue }
if (thisObject.payload.node.type === 'Position Rate' && nearbyNode.positionRate !== undefined) { continue }
if (thisObject.payload.node.type === 'Take Position Event' && nearbyNode.takePosition !== undefined) { continue }
if (thisObject.payload.node.type === 'Trigger Off Event' && nearbyNode.triggerOff !== undefined) { continue }
if (thisObject.payload.node.type === 'Trigger On Event' && nearbyNode.triggerOn !== undefined) { continue }
if (thisObject.payload.node.type === 'Initial Definition' && nearbyNode.initialDefinition !== undefined) { continue }
if (thisObject.payload.node.type === 'Open Execution' && nearbyNode.openExecution !== undefined) { continue }
if (thisObject.payload.node.type === 'Close Execution' && nearbyNode.closeExecution !== undefined) { continue }
if (thisObject.payload.node.type === 'Stop' && nearbyNode.stopLoss !== undefined) { continue }
if (thisObject.payload.node.type === 'Take Profit' && nearbyNode.takeProfit !== undefined) { continue }
if (thisObject.payload.node.type === 'Formula' && nearbyNode.formula !== undefined) { continue }
if (thisObject.payload.node.type === 'Next Phase Event' && nearbyNode.nextPhaseEvent !== undefined) { continue }
if (thisObject.payload.node.type === 'Javascript Code' && nearbyNode.javascriptCode !== undefined) { continue }
/* Here we check if the subtypes are compatible. */
if (nearbyNode.subType !== undefined && compatibleSubTypes !== undefined) {
if (compatibleSubTypes.indexOf('->' + nearbyNode.subType + '->') < 0) {
continue
}
}
/* Discard Phases without partent */
if (thisObject.payload.node.type === 'Phase' && nearbyNode.type === 'Phase' && nearbyNode.payload.parentNode === undefined) { continue }
/* Control maxPhases */
@@ -752,61 +442,18 @@ function newUiObject () {
let nearbyFloatingObjects = thisObject.payload.floatingObject.nearbyFloatingObjects
let compatibleTypes
let compatibleSubTypes
switch (thisObject.payload.node.type) {
case 'Backtesting Session':
compatibleTypes = '->' + 'Definition' + '->'
compatibleSubTypes = undefined
break
case 'Live Trading Session':
compatibleTypes = '->' + 'Definition' + '->'
compatibleSubTypes = undefined
break
case 'Paper Trading Session':
compatibleTypes = '->' + 'Definition' + '->'
compatibleSubTypes = undefined
break
case 'Fordward Testing Session':
compatibleTypes = '->' + 'Definition' + '->'
compatibleSubTypes = undefined
break
case 'Output Dataset':
compatibleTypes = '->' + 'Dataset Definition' + '->'
compatibleSubTypes = undefined
break
case 'Data Dependency':
compatibleTypes = '->' + 'Dataset Definition' + '->'
compatibleSubTypes = undefined
break
case 'Status Dependency':
compatibleTypes = '->' + 'Status Report' + '->'
compatibleSubTypes = undefined
break
case 'Execution Started Event':
compatibleTypes = '->' + 'Execution Finished Event' + '->'
compatibleSubTypes = undefined
break
case 'Process Instance':
compatibleTypes = '->' + 'Process Definition' + '->'
compatibleSubTypes = undefined
break
case 'Product Definition':
compatibleTypes = '->' + 'Plotter Module' + '->'
compatibleSubTypes = undefined
break
default:
let nodeDefinition = APP_SCHEMA_MAP.get(thisObject.payload.node.type)
if (nodeDefinition !== undefined) {
if (nodeDefinition.referenceAttachesTo !== undefined) {
compatibleTypes = nodeDefinition.referenceAttachesTo.compatibleTypes
compatibleSubTypes = nodeDefinition.referenceAttachesTo.compatibleSubTypes
} else {
return
}
} else {
return
}
let nodeDefinition = APP_SCHEMA_MAP.get(thisObject.payload.node.type)
if (nodeDefinition !== undefined) {
if (nodeDefinition.referenceAttachesTo !== undefined) {
compatibleTypes = nodeDefinition.referenceAttachesTo.compatibleTypes
} else {
return
}
} else {
return
}
let foundCompatible = false
referenceAttachToNode = undefined
isReferenceAttaching = false
@@ -817,13 +464,6 @@ function newUiObject () {
let floatingObject = nearby[1]
let nearbyNode = floatingObject.payload.node
if (compatibleTypes.indexOf('->' + nearbyNode.type + '->') >= 0) {
/* Here we check if the subtypes are compatible. */
if (nearbyNode.subType !== undefined && compatibleSubTypes !== undefined) {
if (compatibleSubTypes.indexOf('->' + nearbyNode.subType + '->') < 0) {
continue
}
}
if (foundCompatible === false) {
if (distance < thisObject.container.frame.radius * 1.5 + floatingObject.container.frame.radius * 1.5) {
nearbyNode.payload.uiObject.getReadyToReferenceAttach()
@@ -956,11 +596,19 @@ function newUiObject () {
thisObject.circularProgressBar.fitFunction = thisObject.fitFunction
thisObject.circularProgressBar.container = thisObject.container
/* We will wait to the event that the execution was terminated in order to call back the menu item */
/* We will wait to hear the first onHeartBeat in order to confirm the execution was really started */
let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id
systemEventHandler.listenToEvent(key, 'Running', undefined, key, undefined, onRunning)
systemEventHandler.listenToEvent(key, 'Heartbeat', undefined, 'UiObject', onResponse, onHeartBeat)
function onResponse (message) {
eventSubscriptionIdHeartbeat = message.eventSubscriptionId
}
function onHeartBeat () {
if (thisObject.payload === undefined) { return }
let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id
systemEventHandler.stopListening(key, eventSubscriptionIdHeartbeat, 'UiObject')
function onRunning () {
if (callBackFunction !== undefined) {
callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE)
}
@@ -988,9 +636,14 @@ function newUiObject () {
function stop (callBackFunction, event) {
/* We will wait to the event that the execution was terminated in order to call back the menu item */
let key = thisObject.payload.node.name + '-' + thisObject.payload.node.type + '-' + thisObject.payload.node.id
systemEventHandler.listenToEvent(key, 'Stopped', undefined, key, undefined, onStopped)
systemEventHandler.listenToEvent(key, 'Stopped', undefined, 'UiObject', onResponse, onStopped)
function onResponse (message) {
eventSubscriptionIdOnStopped = message.eventSubscriptionId
}
function onStopped () {
if (thisObject.payload === undefined) { return }
if (callBackFunction !== undefined) {
callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE, event)
}
@@ -1005,6 +658,42 @@ function newUiObject () {
function iconPhysics () {
icon = canvas.designerSpace.iconByUiObjectType.get(thisObject.payload.node.type)
let nodeDefinition = APP_SCHEMA_MAP.get(thisObject.payload.node.type)
if (nodeDefinition.alternativeIcons !== undefined) {
let nodeToUse = thisObject.payload.node
if (nodeDefinition.alternativeIcons === 'Use Reference Parent') {
if (thisObject.payload.node.payload.referenceParent !== undefined) {
nodeToUse = thisObject.payload.node.payload.referenceParent
}
}
if (nodeDefinition.alternativeIcons === 'Use Reference Grandparent') {
if (thisObject.payload.node.payload.referenceParent !== undefined) {
if (thisObject.payload.node.payload.referenceParent.payload.referenceParent !== undefined) {
nodeToUse = thisObject.payload.node.payload.referenceParent.payload.referenceParent
}
}
}
nodeDefinition = APP_SCHEMA_MAP.get(nodeToUse.type)
let code = nodeToUse.code
try {
code = JSON.parse(code)
let alternativeIcon
let iconName
for (let i = 0; i < nodeDefinition.alternativeIcons.length; i++) {
alternativeIcon = nodeDefinition.alternativeIcons[i]
if (alternativeIcon.codeName === code.codeName) {
iconName = alternativeIcon.iconName
}
}
let newIcon = canvas.designerSpace.iconCollection.get(iconName)
if (newIcon !== undefined) {
icon = newIcon
}
} catch (err) {
// Nothing to do if JSON is baddly formated.
}
}
executingIcon = canvas.designerSpace.iconCollection.get('attractive')
}
@@ -1130,25 +819,30 @@ function newUiObject () {
}
let drawMenu = true
let drawTitle = true
if (thisObject.codeEditor !== undefined) {
if (thisObject.codeEditor.visible === true) {
drawMenu = false
drawTitle = false
}
}
if (thisObject.configEditor !== undefined) {
if (thisObject.configEditor.visible === true) {
drawMenu = false
drawTitle = false
}
}
if (thisObject.conditionEditor !== undefined) {
if (thisObject.conditionEditor.visible === true) {
drawMenu = false
drawTitle = false
}
}
if (thisObject.formulaEditor !== undefined) {
if (thisObject.formulaEditor.visible === true) {
drawMenu = false
drawTitle = false
}
}
@@ -1163,7 +857,10 @@ function newUiObject () {
drawErrorMessage()
drawValue()
drawText()
thisObject.uiObjectTitle.draw()
if (drawTitle === true) {
thisObject.uiObjectTitle.draw()
}
}
}
@@ -1171,8 +868,8 @@ function newUiObject () {
if (thisObject.payload.chainParent === undefined) { return }
let targetPoint = {
x: thisObject.payload.targetPosition.x,
y: thisObject.payload.targetPosition.y
x: thisObject.payload.chainParent.payload.floatingObject.container.frame.position.x,
y: thisObject.payload.chainParent.payload.floatingObject.container.frame.position.y
}
let position = {
@@ -1184,10 +881,8 @@ function newUiObject () {
position = thisObject.container.frame.frameThisPoint(position)
if (thisObject.container.frame.radius > 1) {
/* Target Line */
let LINE_STYLE = UI_COLOR.TITANIUM_YELLOW
if (thisObject.payload.floatingObject.isTensed === true) {
if (thisObject.payload.floatingObject.angleToParent !== ANGLE_TO_PARENT.NOT_FIXED) {
LINE_STYLE = UI_COLOR.GOLDEN_ORANGE
}
if (thisObject.payload.floatingObject.isFrozen === true) {
@@ -1214,8 +909,6 @@ function newUiObject () {
}
if (thisObject.container.frame.radius > 0.5) {
/* Target Spot */
let radius = 1
browserCanvasContext.beginPath()
@@ -1248,8 +941,6 @@ function newUiObject () {
let LINE_STYLE = UI_COLOR.GREY
if (thisObject.container.frame.radius > 1) {
/* Target Line */
browserCanvasContext.beginPath()
browserCanvasContext.moveTo(position.x, position.y)
browserCanvasContext.lineTo(targetPoint.x, targetPoint.y)
@@ -1270,8 +961,6 @@ function newUiObject () {
}
if (thisObject.container.frame.radius > 0.5) {
/* Target Spot */
let radius = 1
browserCanvasContext.beginPath()
@@ -1377,11 +1066,13 @@ function newUiObject () {
let label
if (radius > 6) {
const MAX_LABEL_LENGTH = 30
const MAX_LABEL_LENGTH = 65
label = currentValue
if (!isNaN(label)) {
label = currentValue.toFixed(2)
if (currentValue.toFixed !== undefined) {
label = currentValue.toFixed(2)
}
}
if (label !== undefined) {
@@ -1500,25 +1191,28 @@ function newUiObject () {
browserCanvasContext.fill()
if (thisObject.payload.node.type === 'Definition' || thisObject.payload.node.type === 'Network' || thisObject.payload.node.type === 'Team') {
VISIBLE_RADIUS = thisObject.container.frame.radius * 2
let OPACITY = 1
let nodeDefinition = APP_SCHEMA_MAP.get(thisObject.payload.node.type)
if (nodeDefinition !== undefined) {
if (nodeDefinition.isHierarchyHead === true) {
VISIBLE_RADIUS = thisObject.container.frame.radius * 2
let OPACITY = 1
browserCanvasContext.beginPath()
browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true)
browserCanvasContext.closePath()
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.LIGHT_GREY + ', ' + OPACITY + ')'
browserCanvasContext.lineWidth = 10
browserCanvasContext.setLineDash([4, 16])
browserCanvasContext.stroke()
browserCanvasContext.beginPath()
browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true)
browserCanvasContext.closePath()
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.LIGHT_GREY + ', ' + OPACITY + ')'
browserCanvasContext.lineWidth = 10
browserCanvasContext.setLineDash([4, 16])
browserCanvasContext.stroke()
browserCanvasContext.beginPath()
browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true)
browserCanvasContext.closePath()
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.LIGHT_GREY + ', ' + OPACITY + ')'
browserCanvasContext.lineWidth = 1
browserCanvasContext.setLineDash([20, 20])
browserCanvasContext.stroke()
browserCanvasContext.beginPath()
browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true)
browserCanvasContext.closePath()
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.LIGHT_GREY + ', ' + OPACITY + ')'
browserCanvasContext.lineWidth = 1
browserCanvasContext.setLineDash([20, 20])
browserCanvasContext.stroke()
}
}
if (thisObject.isOnFocus === true) {
@@ -1619,7 +1313,7 @@ function newUiObject () {
browserCanvasContext.beginPath()
browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true)
browserCanvasContext.closePath()
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.LIGHT_GREY + ', ' + OPACITY + ')'
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.GOLDEN_ORANGE + ', ' + OPACITY + ')'
browserCanvasContext.lineWidth = 10
browserCanvasContext.setLineDash([10, 90])
browserCanvasContext.stroke()
@@ -1627,7 +1321,7 @@ function newUiObject () {
browserCanvasContext.beginPath()
browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true)
browserCanvasContext.closePath()
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.LIGHT_GREY + ', ' + OPACITY + ')'
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.GOLDEN_ORANGE + ', ' + OPACITY + ')'
browserCanvasContext.lineWidth = 5
browserCanvasContext.setLineDash([5, 45])
browserCanvasContext.stroke()
@@ -1635,7 +1329,7 @@ function newUiObject () {
browserCanvasContext.beginPath()
browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true)
browserCanvasContext.closePath()
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.LIGHT_GREY + ', ' + OPACITY + ')'
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.GOLDEN_ORANGE + ', ' + OPACITY + ')'
browserCanvasContext.lineWidth = 1
browserCanvasContext.setLineDash([2, 8])
browserCanvasContext.stroke()
@@ -1668,7 +1362,7 @@ function newUiObject () {
if (icon !== undefined) {
if (icon.canDrawIcon === true) {
let additionalImageSize = 0
if (thisObject.isExecuting === true) { additionalImageSize = 20 }
if (thisObject.isExecuting === true || isReadyToReferenceAttach === true || isReadyToChainAttach === true) { additionalImageSize = 20 }
let totalImageSize = additionalImageSize + thisObject.payload.floatingObject.currentImageSize
browserCanvasContext.drawImage(
+59 -29
View File
@@ -31,15 +31,21 @@ function newUiObjectConstructor () {
floatingObject.initialize('UI Object', payload)
payload.floatingObject = floatingObject
if (payload.node.savedPayload !== undefined) {
/*
When this object is created based on a backup, share or clone, we will have a savedPayload that we will use to set the initial properties.
If it is a new object being created out of the user interface, we jusst continue with the construction process.
*/
if (userAddingNew === false && payload.node.type !== 'Workspace') {
let position = {
x: 0,
y: 0
}
position = {
x: payload.node.savedPayload.position.x,
y: payload.node.savedPayload.position.y
}
if (position.x === null) { position.x = spawnPosition.x }
if (position.y === null) { position.y = spawnPosition.y }
floatingObject.setPosition(position)
payload.node.savedPayload.position = undefined
if (payload.node.savedPayload.floatingObject.isPinned === true) {
@@ -51,16 +57,18 @@ function newUiObjectConstructor () {
if (payload.node.savedPayload.floatingObject.isCollapsed === true) {
floatingObject.collapseToggle()
}
if (payload.node.savedPayload.floatingObject.isTensed === true) {
floatingObject.tensionToggle()
if (payload.node.savedPayload.floatingObject.angleToParent !== undefined) {
floatingObject.angleToParent = payload.node.savedPayload.floatingObject.angleToParent
}
if (payload.node.savedPayload.floatingObject.distanceToParent !== undefined) {
floatingObject.distanceToParent = payload.node.savedPayload.floatingObject.distanceToParent
}
}
/* For brand new objects being created directly by the user, we will make them inherit some properties from their parents. */
if (userAddingNew === true) {
/* For brand new objects being created directly by the user, we will make them inherit some properties from their parents. */
if (payload.parentNode.payload.floatingObject.isTensed === true) {
floatingObject.tensionToggle()
}
floatingObject.angleToParent = payload.parentNode.payload.floatingObject.angleToParent
floatingObject.distanceToParent = payload.parentNode.payload.floatingObject.distanceToParent
}
let uiObject = newUiObject()
@@ -76,8 +84,8 @@ function newUiObjectConstructor () {
for (let j = 0; j < menuItems.length; j++) {
let item = menuItems[j]
item.angle = undefined
if (item.action.indexOf('Add ') >= 0) {
// item.action = 'Add UI Object'
if (item.action.indexOf('Add ') >= 0 && item.action.indexOf('Missing') >= 0) {
item.action = 'Add Missing Children'
}
if (item.action.indexOf('Delete ') >= 0) {
// item.action = 'Delete UI Object'
@@ -128,24 +136,40 @@ function newUiObjectConstructor () {
iconPathOff: 'menu-fix-unpinned',
rawRadius: 8,
targetRadius: 0,
currentRadius: 0
currentRadius: 0,
ring: 1
}
)
menuItemsInitialValues.push(
{
action: 'Tense / Untense',
actionFunction: floatingObject.tensionToggle,
actionStatus: floatingObject.getTensionStatus,
action: 'Change Tension Level',
actionFunction: floatingObject.angleToParentToggle,
actionStatus: floatingObject.getAngleToParent,
currentStatus: true,
label: undefined,
visible: true,
iconPathOn: 'menu-tensor-fixed-angles',
iconPathOff: 'menu-tensor-free-angles',
icons: ['angle-to-parent-000', 'angle-to-parent-360', 'angle-to-parent-180', 'angle-to-parent-090', 'angle-to-parent-045'],
rawRadius: 8,
targetRadius: 0,
currentRadius: 0
currentRadius: 0,
ring: 1
}
)
menuItemsInitialValues.push(
{
action: 'change Distance to Paarent',
actionFunction: floatingObject.distanceToParentToggle,
actionStatus: floatingObject.getDistanceToParent,
currentStatus: true,
label: undefined,
visible: true,
icons: ['distance-to-parent-000', 'distance-to-parent-025', 'distance-to-parent-050', 'distance-to-parent-100', 'distance-to-parent-150', 'distance-to-parent-200'],
rawRadius: 8,
targetRadius: 0,
currentRadius: 0,
ring: 1
}
)
menuItemsInitialValues.push(
{
action: 'Freeze / Unfreeze',
@@ -158,7 +182,8 @@ function newUiObjectConstructor () {
iconPathOff: 'menu-mobility-freeze',
rawRadius: 8,
targetRadius: 0,
currentRadius: 0
currentRadius: 0,
ring: 1
}
)
menuItemsInitialValues.push(
@@ -173,7 +198,8 @@ function newUiObjectConstructor () {
iconPathOff: 'menu-tree-minus',
rawRadius: 8,
targetRadius: 0,
currentRadius: 0
currentRadius: 0,
ring: 1
}
)
menuItemsInitialValues.push(
@@ -186,7 +212,8 @@ function newUiObjectConstructor () {
iconPathOff: 'menu-backup',
rawRadius: 8,
targetRadius: 0,
currentRadius: 0
currentRadius: 0,
ring: 2
}
)
menuItemsInitialValues.push(
@@ -199,7 +226,8 @@ function newUiObjectConstructor () {
iconPathOff: 'clone',
rawRadius: 8,
targetRadius: 0,
currentRadius: 0
currentRadius: 0,
ring: 2
}
)
if (isPersonalData !== true) {
@@ -213,9 +241,10 @@ function newUiObjectConstructor () {
iconPathOff: 'menu-share',
rawRadius: 8,
targetRadius: 0,
currentRadius: 0
currentRadius: 0,
ring: 2
}
)
)
}
}
@@ -302,6 +331,7 @@ function newUiObjectConstructor () {
switch (payload.node.type) {
case 'Workspace': {
level_0()
floatingObject.angleToParent = ANGLE_TO_PARENT.RANGE_360
break
}
@@ -361,7 +391,7 @@ function newUiObjectConstructor () {
floatingObject.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', 1)'
if (payload.node.savedPayload === undefined) {
// floatingObject.tensionToggle()
// floatingObject.angleToParentToggle()
}
}
function level_2 () {
@@ -376,7 +406,7 @@ function newUiObjectConstructor () {
floatingObject.fillStyle = 'rgba(' + UI_COLOR.GREEN + ', 1)'
if (payload.node.savedPayload === undefined) {
// floatingObject.tensionToggle()
// floatingObject.angleToParentToggle()
}
}
function level_3 () {
@@ -391,7 +421,7 @@ function newUiObjectConstructor () {
floatingObject.fillStyle = 'rgba(' + UI_COLOR.RUSTED_RED + ', 1)'
if (payload.node.savedPayload === undefined) {
// floatingObject.tensionToggle()
// floatingObject.angleToParentToggle()
}
}
function level_4 () {
@@ -406,7 +436,7 @@ function newUiObjectConstructor () {
floatingObject.fillStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', 1)'
if (payload.node.savedPayload === undefined) {
// floatingObject.tensionToggle()
// floatingObject.angleToParentToggle()
}
}
function level_5 () {
+71 -103
View File
@@ -48,106 +48,10 @@ function newUiObjectTitle () {
thisObject.payload = payload
thisObject.allwaysVisible = false // Default value
switch (payload.node.type) {
case 'Definition': {
let nodeDefinition = APP_SCHEMA_MAP.get(thisObject.payload.node.type)
if (nodeDefinition !== undefined) {
if (nodeDefinition.isTitleAllwaysVisible === true) {
thisObject.allwaysVisible = true
break
}
case 'Team': {
thisObject.allwaysVisible = true
break
}
case 'Sensor Bot': {
thisObject.allwaysVisible = true
break
}
case 'Indicator Bot': {
thisObject.allwaysVisible = true
break
}
case 'Trading Bot': {
thisObject.allwaysVisible = true
break
}
case 'Process Definition': {
thisObject.allwaysVisible = true
break
}
case 'Product Definition': {
thisObject.allwaysVisible = true
break
}
case 'Dataset Definition': {
thisObject.allwaysVisible = true
break
}
case 'Record Property': {
thisObject.allwaysVisible = true
break
}
case 'Plotter': {
thisObject.allwaysVisible = true
break
}
case 'Plotter Module': {
thisObject.allwaysVisible = true
break
}
case 'Network': {
thisObject.allwaysVisible = true
break
}
case 'Announcement': {
thisObject.allwaysVisible = true
break
}
case 'Layer': {
thisObject.allwaysVisible = true
break
}
case 'Sensor Bot Instance': {
thisObject.allwaysVisible = true
break
}
case 'Indicator Bot Instance': {
thisObject.allwaysVisible = true
break
}
case 'Backtesting Session': {
thisObject.allwaysVisible = true
break
}
case 'Live Trading Session': {
thisObject.allwaysVisible = true
break
}
case 'Fordward Testing Session': {
thisObject.allwaysVisible = true
break
}
case 'Paper Trading Session': {
thisObject.allwaysVisible = true
break
}
case 'Workspace': {
thisObject.allwaysVisible = true
break
}
case 'Trading System': {
thisObject.allwaysVisible = true
break
}
case 'Strategy': {
thisObject.allwaysVisible = true
break
}
default: {
let nodeDefinition = APP_SCHEMA_MAP.get(thisObject.payload.node.type)
if (nodeDefinition !== undefined) {
if (nodeDefinition.isTitleAllwaysVisible === true) {
thisObject.allwaysVisible = true
}
}
}
}
@@ -178,12 +82,73 @@ function newUiObjectTitle () {
function physics () {
if (thisObject.payload.title === undefined) { return }
/* It is possible to override the default title by setting the APP SCHEMA property 'title' */
let nodeDefinition = APP_SCHEMA_MAP.get(thisObject.payload.node.type)
if (nodeDefinition.title !== undefined) {
thisObject.payload.title = ''
thisObject.payload.node.name = ''
let separator = ''
for (let i = 0; i < nodeDefinition.title.length; i++) {
let titleReference = nodeDefinition.title[i]
switch (titleReference) {
case 'Use Reference Parent': {
let nodeToUse = thisObject.payload.node.payload.referenceParent
if (nodeToUse !== undefined && nodeToUse.payload !== undefined) {
thisObject.payload.title = thisObject.payload.title + separator + nodeToUse.payload.title
thisObject.payload.node.name = thisObject.payload.node.name + separator + nodeToUse.payload.node.name
}
break
}
case 'Use Reference Grandparent': {
let nodeToUse = thisObject.payload.node.payload.referenceParent
if (nodeToUse !== undefined && nodeToUse.payload !== undefined) {
nodeToUse = thisObject.payload.node.payload.referenceParent.payload.referenceParent
if (nodeToUse !== undefined) {
thisObject.payload.title = thisObject.payload.title + separator + nodeToUse.payload.title
thisObject.payload.node.name = thisObject.payload.node.name + separator + nodeToUse.payload.node.name
}
}
break
}
case 'Use Reference Parent Parent': {
let nodeToUse = thisObject.payload.node.payload.referenceParent
if (nodeToUse !== undefined && nodeToUse.payload !== undefined) {
nodeToUse = thisObject.payload.node.payload.referenceParent.payload.parentNode
if (nodeToUse !== undefined && nodeToUse.payload !== undefined) {
thisObject.payload.title = thisObject.payload.title + separator + nodeToUse.payload.title
thisObject.payload.node.name = thisObject.payload.node.name + separator + nodeToUse.payload.node.name
}
}
break
}
case 'Use Reference Parent Parent Parent': {
let nodeToUse = thisObject.payload.node.payload.referenceParent
if (nodeToUse !== undefined && nodeToUse.payload !== undefined) {
nodeToUse = thisObject.payload.node.payload.referenceParent.payload.parentNode
if (nodeToUse !== undefined && nodeToUse.payload !== undefined) {
nodeToUse = thisObject.payload.node.payload.referenceParent.payload.parentNode.payload.parentNode
if (nodeToUse !== undefined && nodeToUse.payload !== undefined) {
thisObject.payload.title = thisObject.payload.title + separator + nodeToUse.payload.title
thisObject.payload.node.name = thisObject.payload.node.name + separator + nodeToUse.payload.node.name
}
}
}
break
}
}
separator = ' '
}
}
let title = trimTitle(thisObject.payload.title)
/* Here we set the dimensions and position of this object */
const FRAME_HEIGHT = 25
const FRAME_WIDTH = title.length / 2 * thisObject.payload.floatingObject.currentFontSize * FONT_ASPECT_RATIO * 1.2 * 2
const Y_OFFSET = -20
const FRAME_WIDTH = (title.length + 2) / 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 - 20 - FRAME_HEIGHT
thisObject.container.frame.position.y = 0 - thisObject.container.frame.radius * 1 / 2 - thisObject.payload.floatingObject.currentFontSize * FONT_ASPECT_RATIO + Y_OFFSET - FRAME_HEIGHT
thisObject.container.frame.width = FRAME_WIDTH
thisObject.container.frame.height = FRAME_HEIGHT
@@ -191,7 +156,7 @@ function newUiObjectTitle () {
if (thisObject.editMode === true) {
let inputPosition = {
x: 0,
y: 0 + CURRENT_TOP_MARGIN
y: 0 + CURRENT_TOP_MARGIN + Y_OFFSET
}
inputPosition = thisObject.container.frame.frameThisPoint(inputPosition)
@@ -213,6 +178,9 @@ function newUiObjectTitle () {
}
function onMouseClick (event) {
let nodeDefinition = APP_SCHEMA_MAP.get(thisObject.payload.node.type)
if (nodeDefinition.title !== undefined) { return }
let checkPoint = {
x: 0,
y: 0
@@ -252,7 +220,7 @@ function newUiObjectTitle () {
}
}
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 = 'resize: none; border: none; outline: none; box-shadow: none; overflow:hidden; font-family: Saira Condensed; 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()
}
+34 -93
View File
@@ -8,6 +8,7 @@ function newFrame () {
containerName: '', // This is for debugging purposes only.
parentFrame: undefined, // Here we store the parent cointainer zoom object.
radius: 0,
offset: undefined,
position: undefined,
container: undefined,
width: browserCanvas.width,
@@ -20,21 +21,30 @@ function newFrame () {
isThisPointHere: isThisPointHere, // This function return true is the point received as parameter lives within this frame.
isThisScreenPointHere: isThisScreenPointHere,
isInViewPort: isInViewPort,
canYouMoveHere: canYouMoveHere,
initialize: initialize
initialize: initialize,
finalize: finalize
}
return thisObject
function finalize () {
thisObject.parentFrame = undefined
thisObject.position = undefined
thisObject.offset = undefined
}
function initialize (pType) {
if (pType !== undefined) { thisObject.type = pType }
let position = {
thisObject.position = {
x: 0,
y: 0
}
thisObject.position = position
thisObject.offset = {
x: 0,
y: 0
}
}
function getBodyHeight () {
@@ -42,7 +52,7 @@ function newFrame () {
}
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 */
/* This function is usefull to know if the object who has this frame is currently appearing at least in part at the canvas.chartSpace.viewport */
point1 = {
x: 0,
@@ -59,7 +69,7 @@ function newFrame () {
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) {
if (point1.x < canvas.chartSpace.viewport.visibleArea.topRight.x && point1.y < canvas.chartSpace.viewport.visibleArea.bottomRight.y && point3.x > canvas.chartSpace.viewport.visibleArea.bottomLeft.x && point3.y > canvas.chartSpace.viewport.visibleArea.topLeft.y) {
return true
} else {
return false
@@ -87,11 +97,11 @@ function newFrame () {
if (thisObject.parentFrame !== undefined) {
parentPoint = thisObject.parentFrame.frameThisPoint(checkPoint)
returnPoint.x = parentPoint.x + thisObject.position.x
returnPoint.y = parentPoint.y + thisObject.position.y
returnPoint.x = parentPoint.x + thisObject.position.x + thisObject.offset.x
returnPoint.y = parentPoint.y + thisObject.position.y + thisObject.offset.y
} else {
returnPoint.x = checkPoint.x + thisObject.position.x
returnPoint.y = checkPoint.y + thisObject.position.y
returnPoint.x = checkPoint.x + thisObject.position.x + thisObject.offset.x
returnPoint.y = checkPoint.y + thisObject.position.y + thisObject.offset.y
}
return returnPoint
@@ -150,78 +160,6 @@ function newFrame () {
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.
*/
point1 = {
x: thisObject.position.x,
y: thisObject.position.y
}
point2 = {
x: thisObject.position.x + thisObject.width,
y: thisObject.position.y
}
point3 = {
x: thisObject.position.x + thisObject.width,
y: thisObject.position.y + thisObject.height
}
point4 = {
x: thisObject.position.x,
y: thisObject.position.y + thisObject.height
}
/* Now the transformations. */
if (thisObject.parentFrame !== undefined) {
// If there is not a parent then there is no point to check bounderies.
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. */
point1 = tempDisplacement.displaceThisPoint(point1)
point2 = tempDisplacement.displaceThisPoint(point2)
point3 = tempDisplacement.displaceThisPoint(point3)
point4 = tempDisplacement.displaceThisPoint(point4)
/* We add the actual displacement. */
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 (thisObject.parentFrame.isThisPointHere(point1) === false) {
return false
}
if (thisObject.parentFrame.isThisPointHere(point2) === false) {
return false
}
if (thisObject.parentFrame.isThisPointHere(point3) === false) {
return false
}
if (thisObject.parentFrame.isThisPointHere(point4) === false) {
return false
}
}
return true
}
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.
@@ -236,7 +174,6 @@ function newFrame () {
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 = thisObject.container.displacement.undisplaceThisPoint(checkPoint)
checkPoint = thisObject.container.frame.unframeThisPoint(checkPoint)
} else {
checkPoint = unTransformThisPoint(checkPoint, thisObject.container)
@@ -275,7 +212,9 @@ function newFrame () {
y: thisObject.position.y
}
thisPoint = thisObject.parentFrame.frameThisPoint(thisPoint)
if (thisObject.parentFrame !== undefined) {
thisPoint = thisObject.parentFrame.frameThisPoint(thisPoint)
}
/* Now we check if the resulting point is whin the current Frame. */
@@ -298,9 +237,9 @@ function newFrame () {
}
}
function draw (drawGrid, drawBorders, drawBackground, fitFunction) {
function draw (drawGrid, drawBorders, drawBackground, fitFunction, style) {
if (drawBorders === true) {
borders(fitFunction)
borders(fitFunction, style)
}
if (drawGrid === true) {
@@ -362,6 +301,7 @@ function newFrame () {
browserCanvasContext.lineWidth = 0.1
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.MANGANESE_PURPLE + ', 0.75)'
browserCanvasContext.setLineDash([0, 0])
browserCanvasContext.stroke()
/* print the title */
@@ -391,7 +331,7 @@ function newFrame () {
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y)
}
function borders (fitFunction) {
function borders (fitFunction, style) {
/* Lest get the important points of the drawing so as to apply the needed transformations. */
let point1
@@ -419,8 +359,7 @@ function newFrame () {
y: thisObject.height
}
/* Now the transformations. */
/* Now the transformations. */
point1 = transformThisPoint(point1, thisObject.container)
point2 = transformThisPoint(point2, thisObject.container)
point3 = transformThisPoint(point3, thisObject.container)
@@ -433,8 +372,7 @@ function newFrame () {
point4 = fitFunction(point4)
}
/* Lets start the drawing. */
/* Lets start the drawing. */
browserCanvasContext.beginPath()
browserCanvasContext.moveTo(point1.x, point1.y)
browserCanvasContext.lineTo(point2.x, point2.y)
@@ -443,8 +381,9 @@ function newFrame () {
browserCanvasContext.lineTo(point1.x, point1.y)
browserCanvasContext.closePath()
browserCanvasContext.strokeStyle = 'rgba(150, 150, 150, 1)'
browserCanvasContext.lineWidth = 1
browserCanvasContext.strokeStyle = 'rgba(' + style.color + ', ' + style.opacity + ')'
browserCanvasContext.lineWidth = style.lineWidth
browserCanvasContext.setLineDash(style.lineDash)
browserCanvasContext.stroke()
browserCanvasContext.closePath()
@@ -506,6 +445,7 @@ function newFrame () {
browserCanvasContext.closePath()
browserCanvasContext.strokeStyle = 'rgba(150, 150, 150, 0.1)'
browserCanvasContext.lineWidth = 1
browserCanvasContext.setLineDash([0, 0])
browserCanvasContext.stroke()
}
@@ -563,6 +503,7 @@ function newFrame () {
browserCanvasContext.closePath()
browserCanvasContext.strokeStyle = 'rgba(100, 100, 100, 0.2)'
browserCanvasContext.lineWidth = 1
browserCanvasContext.setLineDash([0, 0])
browserCanvasContext.stroke()
}
}
+36 -46
View File
@@ -1,20 +1,19 @@
/* User Interface Colors */
const STORAGE_PROVIDER = 'AAWeb';
const CANVAS_APP_NAME = 'Canvas App'
const SUPPORTED_EXCHANGES = ["Poloniex"];
const SUPPORTED_MARKETS = [
{
assetA: "USDT",
assetB: "BTC",
baseAsset: "USDT",
quotedAsset: "BTC",
}
];
const DEFAULT_EXCHANGE = "Poloniex";
const DEFAULT_MARKET = {
assetA: "USDT",
assetB: "BTC",
baseAsset: "USDT",
quotedAsset: "BTC",
};
UI_COLOR = {
@@ -38,17 +37,35 @@ UI_COLOR = {
/* User Interface Fonts */
UI_FONT = {
PRIMARY: "Saira",
PRIMARY: "Saira Condensed",
SECONDARY: "Source Code Pro"
};
FONT_ASPECT_RATIO = 0.45;
const MIN_ZOOM_LEVEL = -28.25
let FONT_ASPECT_RATIO = 0.32;
const GET_CONTAINER_PURPOSE = {
MOUSE_OVER: 1,
MOUSE_WHEEL: 2,
MOUSE_CLICK: 3
MOUSE_CLICK: 3,
DRAGGING: 4
}
const ANGLE_TO_PARENT = {
NOT_FIXED: 0,
RANGE_360: 1,
RANGE_180: 2,
RANGE_90: 3,
RANGE_45: 4
}
const DISTANCE_TO_PARENT = {
NOT_FIXED: 0,
PARENT_025X: 1,
PARENT_050X: 2,
PARENT_100X: 3,
PARENT_150X: 4,
PARENT_200X: 5
}
/* User Interface Panels */
@@ -57,11 +74,13 @@ UI_PANEL = {
WIDTH: {
SMALL: 100,
NORMAL: 150,
MEDIUM: 200,
LARGE: 250,
X_LARGE: 350
},
HEIGHT: {
SMALL: 65,
MEDIUM: 90,
NORMAL: 300,
LARGE: 450
}
@@ -97,31 +116,6 @@ let dailyFilePeriods =
dailyFilePeriods = JSON.parse(dailyFilePeriods);
function convertTimePeriodToName(pTimePeriod) {
for (let i = 0; i < dailyFilePeriods.length; i++) {
let period = dailyFilePeriods[i];
if (period[0] === pTimePeriod) {
return period[1];
}
}
for (let i = 0; i < marketFilesPeriods.length; i++) {
let period = marketFilesPeriods[i];
if (period[0] === pTimePeriod) {
return period[1];
}
}
}
window.AT_BREAKPOINT = false;
let testUser = window.localStorage.getItem("test_user")
@@ -140,7 +134,7 @@ const DEFAULT_CONFIG_TEXT = '// Write your config here'
const DEFAULT_FORMULA_TEXT = '// Write your formula here'
const DEFAULT_CODE_TEXT = '// Write your code here'
const USDT_BTC_HTH = 19900; // This is needed to know the scale of the market time line.
const MAX_DEFAULT_RATE_SCALE_VALUE = 35000; // This is needed to know the scale of the market time line.
const WIDHTER_VOLUME_BAR_BASE_FACTOR = 2.5;
const LESS_WIDHTER_VOLUME_BAR_TOP_FACTOR = 1 / 4;
@@ -166,9 +160,9 @@ const _3_MINUTES_IN_MILISECONDS = 3 * 60 * 1000;
const _2_MINUTES_IN_MILISECONDS = 2 * 60 * 1000;
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 NEW_SESSION_INITIAL_DATE = new Date(); // This value will be overwritten at the canvas.chartSpace.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 INITIAL_TIME_PERIOD = ONE_DAY_IN_MILISECONDS // This value will be overwritten at the canvas.chartSpace.viewport.initialize if the user had a prevous session with this same browser.
let VERY_LARGE_NUMBER = 100000000000
let CURRENT_TOP_MARGIN = window.canvasApp.topMargin
@@ -181,13 +175,13 @@ maxDate.setDate(maxDate.getDate() + 365 * 1); // We might have charts that proj
const MIN_PLOTABLE_DATE = new Date(2015, 0, 1, 0, 0, 0);
const MAX_PLOTABLE_DATE = maxDate;
const TOP_SPACE_HEIGHT = 5;
const COCKPIT_SPACE_HEIGHT = 40;
const TOP_SPACE_HEIGHT = 2
const COCKPIT_SPACE_HEIGHT = 30;
const BREAKPOINT_HEIGHT = 15;
const SIDE_PANEL_WIDTH = 450
let COCKPIT_SPACE_POSITION = browserCanvas.height - COCKPIT_SPACE_HEIGHT
const PRODUCT_CARD_STATUS = {
const LAYER_STATUS = {
ON: 'on',
LOADING: 'loading',
OFF: 'off'
@@ -207,16 +201,12 @@ const PERIOD_10_MIN = "10-min";
const PERIOD_05_MIN = "05-min";
const PERIOD_01_MIN = "01-min";
/*
We define here the size of the chartSpace. It has to bee enough big in order to accomodate all the charts we expect to display in this space.
*/
const TIME_MACHINE_WIDTH = browserCanvas.width * 1000;
const TIME_MACHINE_HEIGHT = browserCanvas.height * 100;
const TIME_MACHINE_WIDTH = 250;
const TIME_MACHINE_HEIGHT = 250 / 50;
function toRadians(angle) {
return angle * (Math.PI / 180);
+531
View File
@@ -0,0 +1,531 @@
function newLayer () {
const MODULE_NAME = 'Layer'
const ERROR_LOG = true
const logger = newWebDebugLog()
logger.fileName = MODULE_NAME
let thisObject = {
container: undefined,
status: LAYER_STATUS.OFF,
fitFunction: undefined,
payload: undefined,
definition: undefined,
panels: undefined,
physics: physics,
draw: draw,
turnOff: turnOff,
turnOn: turnOn,
setDatetime: setDatetime,
setTimeFrame: setTimeFrame,
onMarketFileLoaded: onMarketFileLoaded,
onDailyFileLoaded: onDailyFileLoaded,
onSingleFileLoaded: onSingleFileLoaded,
onFileSequenceLoaded: onFileSequenceLoaded,
getContainer: getContainer, // returns the inner most container that holds the point received by parameter.
initialize: initialize,
finalize: finalize
}
let LOADING_FILL_STYLE = 'rgba(234, 143, 23, @Opacity)'
let LOADED_FILL_STYLE = 'rgba(45, 232, 28, @Opacity)'
let UNLOADED_FILL_STYLE = 'rgba(226, 226, 226, @Opacity)'
let LOADING_STROKE_STYLE = 'rgba(234, 143, 23, @Opacity)'
let LOADED_STROKE_STYLE = 'rgba(45, 232, 28, @Opacity)'
let UNLOADED_STROKE_STYLE = 'rgba(226, 226, 226, @Opacity)'
let marketFileProgressBar = {
value: 0,
animatedValue: 0,
fillStyle: UNLOADED_FILL_STYLE,
strokeStyle: UNLOADED_STROKE_STYLE,
opacity: 0.00
}
let dailyFileProgressBar = {
value: 0,
animatedValue: 0,
fillStyle: UNLOADED_FILL_STYLE,
strokeStyle: UNLOADED_STROKE_STYLE,
opacity: 0.00
}
let singleFileProgressBar = {
value: 0,
animatedValue: 0,
fillStyle: UNLOADED_FILL_STYLE,
strokeStyle: UNLOADED_STROKE_STYLE,
opacity: 0.00
}
let fileSequenceProgressBar = {
value: 0,
animatedValue: 0,
fillStyle: UNLOADED_FILL_STYLE,
strokeStyle: UNLOADED_STROKE_STYLE,
opacity: 0.00
}
let timeFrame = INITIAL_TIME_PERIOD
let datetime = NEW_SESSION_INITIAL_DATE
/* Add an Event Handler */
thisObject.eventHandler = newEventHandler()
let imagesLoaded = 0
let onMouseClickEventSuscriptionId
let panelsVisibleButton
return thisObject
function finalize () {
thisObject.container.finalize()
thisObject.eventHandler.finalize()
thisObject.container = undefined
thisObject.eventHandler = undefined
thisObject.status = undefined
thisObject.fitFunction = undefined
thisObject.payload = undefined
thisObject.definition = undefined
thisObject.panels = undefined
timeFrame = undefined
datetime = undefined
LOADING_FILL_STYLE = undefined
LOADED_FILL_STYLE = undefined
UNLOADED_FILL_STYLE = undefined
LOADING_STROKE_STYLE = undefined
LOADED_STROKE_STYLE = undefined
UNLOADED_STROKE_STYLE = undefined
marketFileProgressBar = undefined
dailyFileProgressBar = undefined
singleFileProgressBar = undefined
fileSequenceProgressBar = undefined
panelsVisibleButton = undefined
thisObject.container.eventHandler.stopListening(onMouseClickEventSuscriptionId)
}
function initialize (callBackFunction) {
/* Create this objects continer */
try {
thisObject.container = newContainer()
thisObject.container.initialize(MODULE_NAME + ' ' + thisObject.payload.node.id)
thisObject.container.isDraggeable = false
thisObject.container.isClickeable = true
/* Lets set the basic dimensions of this thisObject. */
let position = {
x: 0,
y: 0
}
thisObject.container.frame.position = position
thisObject.container.frame.width = UI_PANEL.WIDTH.NORMAL
thisObject.container.frame.height = 70
let functionLibraryProtocolNode = newProtocolNode()
let lightingPath =
'->Layer->' +
'Data Product->Single Market Data->' +
'Session Independent Data->Session Based Data->' +
'Session Reference->Backtesting Session->Paper Trading Session->Fordward Testing Session->Live Trading Session->' +
'Market->Market Base Asset->Asset->' +
'Market Quoted Asset->Asset->' +
'Exchange Markets->Crypto Exchange->' +
'Product Definition->' +
'Sensor Bot->Indicator Bot->Trading Bot->' +
'Data Mine->' +
'Dataset Definition->' +
'Record Definition->Record Property->Formula->' +
'Data Building Procedure->Procedure Loop->Javascript Code->Procedure Initialization->Javascript Code->' +
'Calculations Procedure->Procedure Loop->Javascript Code->Procedure Initialization->Javascript Code->' +
'Plotter Module->Plotter->' +
'Shapes->' +
'Chart Points->Point->Point Formula->' +
'Polygon->Polygon Body->Style->Style Condition->Style->' +
'Polygon Border->Style->Style Condition->Style->' +
'Polygon Vertex->Point->' +
'Plotter Panel->Javascript Code->Panel Data->Data Formula->'
thisObject.definition = functionLibraryProtocolNode.getProtocolNode(thisObject.payload.node, false, true, true, false, false, lightingPath)
/* Here we validate that we have all the needed information */
if (thisObject.definition.referenceParent === undefined) { return }
if (thisObject.definition.referenceParent.parentNode === undefined) { return }
if (thisObject.definition.referenceParent.parentNode.referenceParent === undefined) { return }
if (thisObject.definition.referenceParent.parentNode.referenceParent.parentNode === undefined) { return }
if (thisObject.definition.referenceParent.parentNode.referenceParent.parentNode.parentNode === undefined) { return }
if (thisObject.definition.referenceParent.parentNode.referenceParent.baseAsset === undefined) { return }
if (thisObject.definition.referenceParent.parentNode.referenceParent.baseAsset.referenceParent === undefined) { return }
if (thisObject.definition.referenceParent.parentNode.referenceParent.quotedAsset === undefined) { return }
if (thisObject.definition.referenceParent.parentNode.referenceParent.quotedAsset.referenceParent === undefined) { return }
if (thisObject.definition.referenceParent.referenceParent === undefined) { return }
if (thisObject.definition.referenceParent.referenceParent.parentNode === undefined) { return }
if (thisObject.definition.referenceParent.referenceParent.parentNode.parentNode === undefined) { return }
/* Lets listen to our own events to react when we have a Mouse Click */
onMouseClickEventSuscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick)
callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE)
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> err = ' + err.stack) }
}
}
function getContainer (point) {
if (panelsVisibleButton !== undefined) {
let container = panelsVisibleButton.getContainer(point)
if (container !== undefined) {
return container
}
}
if (thisObject.container.frame.isThisPointHere(point, true) === true) {
return thisObject.container
}
}
function setDatetime (pDatetime) {
/*
When the datetime changes from one day to another, this forces cursors to potentially load more files, thus we reset this counter and
get ready to receive events on files loaded.
*/
let currentDate = Math.trunc(datetime.valueOf() / ONE_DAY_IN_MILISECONDS)
let newDate = Math.trunc(pDatetime.valueOf() / ONE_DAY_IN_MILISECONDS)
datetime = pDatetime
if (currentDate !== newDate) {
if (timeFrame <= _1_HOUR_IN_MILISECONDS) {
dailyFileProgressBar.animatedValue = 0
}
}
}
function setTimeFrame (pTimeFrame) {
/*
When the time period below or equal to 1 hour changes, this forces cursors to potentially load more files, thus we reset this counter and
get ready to receive events on files loaded.
*/
if (timeFrame !== pTimeFrame) {
timeFrame = pTimeFrame
if (timeFrame <= _1_HOUR_IN_MILISECONDS) {
dailyFileProgressBar.animatedValue = 0
}
}
}
function onMarketFileLoaded (event) {
marketFileProgressBar.value = Math.trunc(event.totalValue * 100 / event.totalValue)
marketFileProgressBar.fillStyle = LOADING_FILL_STYLE
marketFileProgressBar.strokeStyle = LOADING_STROKE_STYLE
if (marketFileProgressBar.value > 100) { marketFileProgressBar.value = 100 }
}
function onDailyFileLoaded (event) {
dailyFileProgressBar.value = Math.trunc(event.currentValue * 100 / event.totalValue)
dailyFileProgressBar.fillStyle = LOADING_FILL_STYLE
dailyFileProgressBar.strokeStyle = LOADING_STROKE_STYLE
if (dailyFileProgressBar.value > 100) { dailyFileProgressBar.value = 100 }
}
function onSingleFileLoaded (event) {
singleFileProgressBar.value = Math.trunc(event.currentValue * 100 / event.totalValue)
singleFileProgressBar.fillStyle = LOADING_FILL_STYLE
singleFileProgressBar.strokeStyle = LOADING_STROKE_STYLE
if (singleFileProgressBar.value > 100) { singleFileProgressBar.value = 100 }
}
function onFileSequenceLoaded (event) {
fileSequenceProgressBar.value = Math.trunc(event.currentValue * 100 / event.totalValue)
fileSequenceProgressBar.fillStyle = LOADING_FILL_STYLE
fileSequenceProgressBar.strokeStyle = LOADING_STROKE_STYLE
if (fileSequenceProgressBar.value > 100) { fileSequenceProgressBar.value = 100 }
}
function turnOff () {
if (thisObject.status !== LAYER_STATUS.OFF) {
resetProgressBars()
changeStatusTo(LAYER_STATUS.OFF)
}
}
function turnOn () {
if (thisObject.status === LAYER_STATUS.OFF) {
resetProgressBars()
changeStatusTo(LAYER_STATUS.LOADING)
}
}
function onMouseClick (event) {
switch (thisObject.status) {
case LAYER_STATUS.ON:
resetProgressBars()
changeStatusTo(LAYER_STATUS.OFF)
break
case LAYER_STATUS.OFF:
resetProgressBars()
changeStatusTo(LAYER_STATUS.LOADING)
break
case LAYER_STATUS.LOADING:
changeStatusTo(LAYER_STATUS.OFF)
break
}
}
function resetProgressBars () {
marketFileProgressBar.animatedValue = 0
marketFileProgressBar.value = 0
marketFileProgressBar.fillStyle = UNLOADED_FILL_STYLE
marketFileProgressBar.strokeStyle = UNLOADED_STROKE_STYLE
dailyFileProgressBar.animatedValue = 0
dailyFileProgressBar.value = 0
dailyFileProgressBar.fillStyle = UNLOADED_FILL_STYLE
dailyFileProgressBar.strokeStyle = UNLOADED_STROKE_STYLE
singleFileProgressBar.animatedValue = 0
singleFileProgressBar.value = 0
singleFileProgressBar.fillStyle = UNLOADED_FILL_STYLE
singleFileProgressBar.strokeStyle = UNLOADED_STROKE_STYLE
fileSequenceProgressBar.animatedValue = 0
fileSequenceProgressBar.value = 0
fileSequenceProgressBar.fillStyle = UNLOADED_FILL_STYLE
fileSequenceProgressBar.strokeStyle = UNLOADED_STROKE_STYLE
}
function physics () {
statusPhysics()
childrenPhysics()
}
function childrenPhysics () {
/* Panels Visible Button Setup */
if (thisObject.status === LAYER_STATUS.ON) {
if (panelsVisibleButton === undefined) {
if (thisObject.panels !== undefined) {
if (thisObject.panels.length > 0) {
panelsVisibleButton = newPanelsVisibleButton()
let storedValue = loadPropertyFromNodeConfig(thisObject.payload, 'showPanels')
if (storedValue !== undefined) {
if (storedValue === true || storedValue === false) {
panelsVisibleButton.showPanels = storedValue
}
}
panelsVisibleButton.initialize(thisObject.panels)
panelsVisibleButton.container.connectToParent(thisObject.container)
}
}
} else {
savePropertyAtNodeConfig(thisObject.payload, 'showPanels', panelsVisibleButton.showPanels)
}
}
}
function statusPhysics () {
/* We retrieve the stored status at the config. */
try {
let storedValue = loadPropertyFromNodeConfig(thisObject.payload, 'status')
if (storedValue !== undefined) {
if (storedValue !== thisObject.status) {
if (storedValue === LAYER_STATUS.ON) {
resetProgressBars()
changeStatusTo(LAYER_STATUS.LOADING)
}
if (storedValue === LAYER_STATUS.OFF) {
resetProgressBars()
changeStatusTo(LAYER_STATUS.OFF)
}
}
} else {
resetProgressBars()
changeStatusTo(LAYER_STATUS.OFF)
}
} catch (err) {
// we ignore errors here since most likely they will be parsing errors.
}
/* Check when the loading finishes */
if (
thisObject.status === LAYER_STATUS.LOADING &&
marketFileProgressBar.value === 100 &&
dailyFileProgressBar.value === 100
) {
changeStatusTo(LAYER_STATUS.ON)
}
}
function changeStatusTo (newStatus) {
if (thisObject.status !== newStatus) {
thisObject.status = newStatus
if (thisObject.status === LAYER_STATUS.OFF) {
if (panelsVisibleButton !== undefined) {
panelsVisibleButton.finalize()
panelsVisibleButton = undefined
}
}
savePropertyAtNodeConfig(thisObject.payload, 'status', thisObject.status)
let eventData = thisObject
thisObject.container.eventHandler.raiseEvent('Status Changed', eventData)
}
}
function draw () {
drawLayer()
if (panelsVisibleButton !== undefined) {
panelsVisibleButton.draw()
}
}
function drawLayer () {
drawLayerDisplay()
}
function drawProgressBar (progressBar, lineWidth, offsetY) {
const ANIMATED_INCREMENT = 5
const OPACITY_INCREMENT = 0.01
const OPACITY_MIN = 1
let point1
let point2
let horizontalMargin = 12
if (progressBar.value === 0) {
return
}
/* Animate */
if (progressBar.animatedValue < progressBar.value) {
progressBar.animatedValue = progressBar.animatedValue + ANIMATED_INCREMENT
progressBar.opacity = progressBar.opacity + OPACITY_INCREMENT
}
if (progressBar.animatedValue >= 100) {
progressBar.animatedValue = 100
progressBar.opacity = progressBar.opacity - OPACITY_INCREMENT
if (progressBar.opacity < OPACITY_MIN) { progressBar.opacity = OPACITY_MIN }
progressBar.strokeStyle = LOADED_STROKE_STYLE.replace('@Opacity', progressBar.opacity.toString())
}
point1 = {
x: 0 + horizontalMargin,
y: thisObject.container.frame.height + offsetY
}
point2 = {
x: (thisObject.container.frame.width - horizontalMargin * 2) * progressBar.animatedValue / 100 + horizontalMargin,
y: thisObject.container.frame.height + offsetY
}
/* Now the transformations. */
point1 = thisObject.container.frame.frameThisPoint(point1)
point2 = thisObject.container.frame.frameThisPoint(point2)
point1 = thisObject.fitFunction(point1)
point2 = thisObject.fitFunction(point2)
browserCanvasContext.beginPath()
browserCanvasContext.moveTo(point1.x, point1.y)
browserCanvasContext.lineTo(point2.x, point2.y)
browserCanvasContext.closePath()
browserCanvasContext.strokeStyle = progressBar.strokeStyle.replace('@Opacity', progressBar.opacity.toString())
browserCanvasContext.setLineDash([1, 4])
browserCanvasContext.lineWidth = lineWidth
browserCanvasContext.stroke()
}
function drawLayerDisplay () {
let baseAsset = thisObject.definition.referenceParent.parentNode.referenceParent.baseAsset.referenceParent
let quotedAsset = thisObject.definition.referenceParent.parentNode.referenceParent.quotedAsset.referenceParent
let market = baseAsset.code.codeName + '/' + quotedAsset.code.codeName
let exchange = thisObject.definition.referenceParent.parentNode.referenceParent.parentNode.parentNode
let plotterModule = thisObject.definition.referenceParent.referenceParent.referenceParent
let label1 = thisObject.payload.node.name
let label2 = exchange.name.substring(0, 15) + ' - ' + market
let label3 = thisObject.status.toUpperCase()
if (label1 !== undefined) {
label1 = label1.substring(0, 22)
}
let icon1 = getIcon(exchange)
let icon2
if (plotterModule.code.icon !== undefined) {
icon2 = canvas.designerSpace.iconCollection.get(plotterModule.code.icon)
}
let icon3 = getIcon(baseAsset)
let icon4 = getIcon(quotedAsset)
function getIcon (node) {
let nodeDefinition = APP_SCHEMA_MAP.get(node.type)
let iconName
if (nodeDefinition.alternativeIcons !== undefined) {
for (let i = 0; i < nodeDefinition.alternativeIcons.length; i++) {
alternativeIcon = nodeDefinition.alternativeIcons[i]
if (alternativeIcon.codeName === node.code.codeName) {
iconName = alternativeIcon.iconName
}
}
}
if (iconName !== undefined) {
icon = canvas.designerSpace.iconCollection.get(iconName)
} else {
icon = canvas.designerSpace.iconCollection.get(nodeDefinition.icon)
}
return icon
}
let backgroundColor = UI_COLOR.BLACK
const RED_LINE_HIGHT = 4
const OPACITY = 0.75
let params = {
cornerRadius: 0,
lineWidth: 1,
container: thisObject.container,
borderColor: UI_COLOR.RUSTED_RED,
castShadow: false,
backgroundColor: backgroundColor,
opacity: OPACITY
}
roundedCornersBackground(params)
drawLabel(label1, 1 / 2, 6 / 10, -5, 0, 17, thisObject.container)
drawLabel(label2, 1 / 2, 8.2 / 10, -5, 0, 9, thisObject.container)
drawLabel(label3, 1 / 2, 9.5 / 10, -5, 0, 9, thisObject.container)
drawProgressBar(marketFileProgressBar, 1, -45)
drawProgressBar(dailyFileProgressBar, 1, -46)
drawProgressBar(singleFileProgressBar, 1, -47)
drawProgressBar(fileSequenceProgressBar, 1, -48)
drawIcon(icon1, 1 / 8, 2 / 10, 0, 0, 14, thisObject.container)
drawIcon(icon2, 7 / 8, 2 / 10, 0, 0, 14, thisObject.container)
drawIcon(icon3, 3.4 / 8, 2 / 10, 0, 0, 14, thisObject.container)
drawIcon(icon4, 4.6 / 8, 2 / 10, 0, 0, 14, thisObject.container)
}
}
+456
View File
@@ -0,0 +1,456 @@
function newLayersPanel () {
let thisObject = {
name: 'Layers Panel',
fitFunction: undefined,
container: undefined,
layers: [],
payload: undefined,
isVisible: true,
panelTabButton: undefined,
physics: physics,
draw: draw,
getContainer: getContainer,
initialize: initialize,
finalize: finalize
}
thisObject.container = newContainer()
thisObject.container.initialize()
thisObject.container.isDraggeable = true
thisObject.container.isWheelable = true
let isInitialized = false
let layersMap = new Map()
let visibleLayers = []
let firstVisibleLayer = 1
const LAYER_SEPARATION = 0
let visible = true
let headerHeight = 40
let footerHeight = 10
let layerHeight = 70
let desiredVisibleLayers = 5
let posibleVisibleLayers = 5
let desiredPanelHeight = (layerHeight + LAYER_SEPARATION) * desiredVisibleLayers + headerHeight + footerHeight
let posiblePanelHeight = (layerHeight + LAYER_SEPARATION) * posibleVisibleLayers + headerHeight + footerHeight
let onMouseWheelEventSuscriptionId
return thisObject
function finalize () {
thisObject.container.eventHandler.stopListening(onMouseWheelEventSuscriptionId)
thisObject.panelTabButton.finalize()
thisObject.panelTabButton = undefined
layersMap = undefined
visibleLayers = undefined
thisObject.container.finalize()
thisObject.container = undefined
thisObject.payload = undefined
thisObject = undefined
}
function initialize () {
thisObject.container.name = thisObject.payload.node.name
thisObject.container.frame.containerName = thisObject.container.name
thisObject.container.frame.width = UI_PANEL.WIDTH.NORMAL
thisObject.container.frame.height = headerHeight
let position = { // Default position
x: canvas.chartSpace.viewport.visibleArea.topLeft.x,
y: canvas.chartSpace.viewport.visibleArea.topLeft.y
}
thisObject.container.frame.position = position
loadFrame(thisObject.payload, thisObject.container.frame)
thisObject.panelTabButton = newPanelTabButton()
thisObject.panelTabButton.parentContainer = thisObject.container
thisObject.panelTabButton.container.frame.parentFrame = thisObject.container.frame
thisObject.panelTabButton.fitFunction = thisObject.fitFunction
thisObject.panelTabButton.initialize()
onMouseWheelEventSuscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseWheel', onMouseWheel)
readObjectState()
isInitialized = true
}
function saveObjectStateVisibleLayers () {
savePropertyAtNodeConfig(thisObject.payload, 'visibleLayers', desiredVisibleLayers)
}
function saveObjectStatePanelLocation () {
savePropertyAtNodeConfig(thisObject.payload, 'panelLocation', thisObject.panelTabButton.status)
}
function readObjectState () {
let storedValue
storedValue = loadPropertyFromNodeConfig(thisObject.payload, 'visibleLayers')
if (isNaN(storedValue) || storedValue === null || storedValue === undefined) {
// not using this value
saveObjectStateVisibleLayers() // this overrides any invalid value at the config.
return
} else {
if (storedValue < 0) { storedValue = 0 }
if (storedValue > thisObject.layers.length) {
storedValue = thisObject.layers.length
}
if (storedValue !== desiredVisibleLayers) {
desiredVisibleLayers = storedValue
desiredPanelHeight = (layerHeight + LAYER_SEPARATION) * desiredVisibleLayers + headerHeight + footerHeight
calculateVisbleLayers()
}
}
storedValue = loadPropertyFromNodeConfig(thisObject.payload, 'panelLocation')
if (storedValue === null || storedValue === undefined) {
// not using this value
saveObjectStatePanelLocation() // this overrides any invalid value at the config.
return
} else {
if (storedValue !== 'up' && storedValue !== 'down') {
saveObjectStatePanelLocation() // this overrides any invalid value at the config.
return
}
thisObject.panelTabButton.setStatus(storedValue)
saveObjectStatePanelLocation()
}
}
function removeLayer (id) {
let layer = layersMap.get(id)
layersMap.delete(id)
layer.turnOff()
layer.container.eventHandler.stopListening(layer.onLayerStatusChangedEventSuscriptionId)
layer.container.eventHandler.stopListening(layer.onMouseWheelEventSuscriptionId)
layer.finalize()
}
function addLayer (layerNode) {
/* Now we create Product objects */
let layer = newLayer()
layer.payload = layerNode.payload
layer.nodeId = layerNode.payload.node.id
layer.fitFunction = thisObject.fitFunction
/* Initialize it */
layer.initialize(onInitialized)
function onInitialized (err) {
if (err.result === GLOBAL.DEFAULT_OK_RESPONSE.result) {
layersMap.set(layerNode.id, layer)
/* Container Stuff */
layer.container.frame.parentFrame = thisObject.container.frame
layer.container.parentContainer = thisObject.container
layer.container.isWheelable = true
/* Add to the Product Array */
thisObject.layers.push(layer)
/* Listen to Status Changes Events */
layer.onLayerStatusChangedEventSuscriptionId = layer.container.eventHandler.listenToEvent('Status Changed', onLayerStatusChanged)
layer.onMouseWheelEventSuscriptionId = layer.container.eventHandler.listenToEvent('onMouseWheel', onMouseWheel)
return layer
}
}
}
function onMouseWheel (event) {
delta = event.wheelDelta
if (delta > 0) {
delta = -1
} else {
delta = 1
}
if (event.y - thisObject.container.frame.position.y - CURRENT_TOP_MARGIN < headerHeight) { // Mouse wheel over the header, not a layer
desiredVisibleLayers = desiredVisibleLayers + delta
if (desiredVisibleLayers < 0) { desiredVisibleLayers = 0 }
if (desiredVisibleLayers > thisObject.layers.length) { desiredVisibleLayers = thisObject.layers.length }
} else {
firstVisibleLayer = firstVisibleLayer + delta
}
desiredPanelHeight = (layerHeight + LAYER_SEPARATION) * desiredVisibleLayers + headerHeight + footerHeight
calculateVisbleLayers()
saveObjectStateVisibleLayers()
}
function panelSizePhysics () {
let viewPortHeight = canvas.chartSpace.viewport.visibleArea.bottomLeft.y - canvas.chartSpace.viewport.visibleArea.topLeft.y
if (viewPortHeight < headerHeight) {
visible = false
} else {
visible = true
}
if (desiredPanelHeight > viewPortHeight) {
posibleVisibleLayers = Math.trunc((viewPortHeight - headerHeight - footerHeight) / (layerHeight + LAYER_SEPARATION))
} else {
posibleVisibleLayers = desiredVisibleLayers
}
if (thisObject.layers.length < posibleVisibleLayers) { posibleVisibleLayers = thisObject.layers.length }
if (posibleVisibleLayers === 0) {
posiblePanelHeight = (layerHeight + LAYER_SEPARATION) * posibleVisibleLayers + headerHeight
} else {
posiblePanelHeight = (layerHeight + LAYER_SEPARATION) * posibleVisibleLayers + headerHeight + footerHeight
}
thisObject.container.frame.height = posiblePanelHeight
}
function calculateVisbleLayers () {
panelSizePhysics()
let availableSlots = posibleVisibleLayers
if (firstVisibleLayer < 1) { firstVisibleLayer = 1 }
if (firstVisibleLayer > (thisObject.layers.length - availableSlots + 1)) { firstVisibleLayer = thisObject.layers.length - availableSlots + 1 }
visibleLayers = []
for (let i = 0; i < thisObject.layers.length; i++) {
if (i + 1 >= firstVisibleLayer && i + 1 < firstVisibleLayer + availableSlots) {
let layer = thisObject.layers[i]
layer.container.frame.position.x = 0
layer.container.frame.position.y = (layerHeight + LAYER_SEPARATION) * visibleLayers.length + headerHeight
/* Add to Visible Product Array */
visibleLayers.push(layer)
}
}
}
function onLayerStatusChanged (layer) {
thisObject.container.eventHandler.raiseEvent('Layer Status Changed', layer)
}
function getContainer (point) {
let container
container = thisObject.panelTabButton.getContainer(point)
if (container !== undefined) { return container }
/* 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 */
for (let i = 0; i < visibleLayers.length; i++) {
container = visibleLayers[i].getContainer(point)
if (container !== undefined) {
let checkPoint = {
x: point.x,
y: point.y
}
checkPoint = thisObject.fitFunction(checkPoint)
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. */
let checkPoint = {
x: point.x,
y: point.y
}
checkPoint = thisObject.fitFunction(checkPoint)
if (point.x === checkPoint.x && point.y === checkPoint.y) {
return thisObject.container
}
}
}
function childrenPhysics () {
for (let i = 0; i < thisObject.layers.length; i++) {
let layer = thisObject.layers[i]
layer.physics()
}
}
function syncWithConfigPhysics () {
readObjectState()
}
function physics () {
if (isInitialized === false) { return }
thisObject.panelTabButton.physics()
saveFrame(thisObject.payload, thisObject.container.frame)
syncWithConfigPhysics()
/*
The overall idea here is that we need to keep syncronized the panel with the layers that are
defined at the Designer. Users can connect or disconnect any objext resulting in changes in which
are valid layers and which not at any point in time. So what we do here is trying to keep the panel
only with the layers that are connected to the Charting Space hiriarcy.
To achieve this, first we are going to move all session related cards to a local array. Then we are
going to check for layers at the designer, and will move back the cards which still have layers well
defined to where they were.
If we find new layers we will add them at that point. Finally, the cards that still remain at the
local array after all the layers at the designer have been processed, are turned off and discarded.
*/
childrenPhysics()
let localLayers = []
moveToLocalLayers()
syncWithDesignerLayers()
/* At this poins all the cards still at the local array need to be removed from the panel. */
turnOffUnusedLayers()
calculateVisbleLayers()
function syncWithDesignerLayers () {
let layerManager = thisObject.payload.node
for (let p = 0; p < layerManager.layers.length; p++) {
let layerNode = layerManager.layers[p]
let found = removeFromLocalLayers(layerNode.id)
if (found !== true) {
layer = addLayer(layerNode)
if (layer !== undefined) {
onLayerStatusChanged(layer)
}
}
}
}
function moveToLocalLayers () {
removeNext()
function removeNext () {
for (let i = 0; i < thisObject.layers.length; i++) {
let layer = thisObject.layers[i]
thisObject.layers.splice(i, 1)
localLayers.push(layer)
removeNext()
}
}
}
function removeFromLocalLayers (id) {
for (let i = 0; i < localLayers.length; i++) {
let layer = localLayers[i]
if (layer.payload.node.id === id) {
thisObject.layers.push(layer)
localLayers.splice(i, 1)
return true
}
}
}
function turnOffUnusedLayers () {
for (let i = 0; i < localLayers.length; i++) {
let layer = localLayers[i]
removeLayer(layer.nodeId)
}
}
}
function draw () {
if (isInitialized === false || visible === false) { return }
// thisObject.container.frame.draw(false, false, false, thisObject.fitFunction)
drawHeader()
for (let i = 0; i < visibleLayers.length; i++) {
visibleLayers[i].draw()
}
drawScrollBar()
thisObject.panelTabButton.draw()
}
function drawHeader () {
let label1 = thisObject.payload.node.payload.parentNode.payload.parentNode.name.substring(0, 18)
let label2 = thisObject.payload.node.payload.parentNode.name.substring(0, 18)
let label3 = ''
let icon1 = canvas.designerSpace.iconByUiObjectType.get(thisObject.payload.node.payload.parentNode.payload.parentNode.type)
let icon2 = canvas.designerSpace.iconByUiObjectType.get(thisObject.payload.node.payload.parentNode.type)
let backgroundColor = UI_COLOR.BLACK
let params = {
cornerRadius: 5,
lineWidth: 1,
container: thisObject.container,
borderColor: UI_COLOR.RUSTED_RED,
castShadow: false,
backgroundColor: backgroundColor,
opacity: 1
}
roundedCornersBackground(params)
drawLabel(label1, 1 / 2, 0, 0, 15, 9, thisObject.container)
drawLabel(label2, 1 / 2, 0, 0, 30, 9, thisObject.container)
drawIcon(icon1, 1 / 8, 0, 0, 20, 28, thisObject.container)
drawIcon(icon2, 7 / 8, 0, 0, 20, 28, thisObject.container)
}
function drawScrollBar () {
if (thisObject.layers.length > posibleVisibleLayers && posibleVisibleLayers > 0) {
let xOffset = 4
let barTopPoint = {
x: thisObject.container.frame.width - xOffset,
y: headerHeight
}
let barBottomPoint = {
x: thisObject.container.frame.width - xOffset,
y: thisObject.container.frame.height - footerHeight
}
let ratio = posibleVisibleLayers / thisObject.layers.length
let handleHeight = (posibleVisibleLayers * (layerHeight + LAYER_SEPARATION)) * ratio
let handleTopPoint = {
x: thisObject.container.frame.width - xOffset,
y: headerHeight + (layerHeight + LAYER_SEPARATION) * ratio * (firstVisibleLayer - 1)
}
let handleBottomPoint = {
x: thisObject.container.frame.width - xOffset,
y: handleTopPoint.y + handleHeight
}
barTopPoint = thisObject.container.frame.frameThisPoint(barTopPoint)
barBottomPoint = thisObject.container.frame.frameThisPoint(barBottomPoint)
handleTopPoint = thisObject.container.frame.frameThisPoint(handleTopPoint)
handleBottomPoint = thisObject.container.frame.frameThisPoint(handleBottomPoint)
browserCanvasContext.beginPath()
browserCanvasContext.moveTo(barTopPoint.x, barTopPoint.y)
browserCanvasContext.lineTo(barBottomPoint.x, barBottomPoint.y)
browserCanvasContext.closePath()
browserCanvasContext.setLineDash([0, 0])
browserCanvasContext.lineWidth = 1
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.GREY + ', ' + 1 + ')'
browserCanvasContext.stroke()
browserCanvasContext.beginPath()
browserCanvasContext.moveTo(handleTopPoint.x, handleTopPoint.y)
browserCanvasContext.lineTo(handleBottomPoint.x, handleBottomPoint.y)
browserCanvasContext.closePath()
browserCanvasContext.setLineDash([0, 0])
browserCanvasContext.lineWidth = 4
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.PATINATED_TURQUOISE + ', ' + 1 + ')'
browserCanvasContext.stroke()
}
}
}
+101 -77
View File
@@ -3,78 +3,121 @@ function newPanelTabButton () {
container: undefined,
fitFunction: undefined,
parentContainer: undefined,
status: undefined,
setStatus: setStatus,
physics: physics,
draw: draw,
getContainer: getContainer, // returns the inner most container that holds the point received by parameter.
initialize: initialize
initialize: initialize,
finalize: finalize
}
let isInitialized = false
/* Cointainer stuff */
var container = newContainer()
container.name = 'Panel Tab Button'
container.initialize()
container.isClickeable = true
thisObject.container = container
thisObject.container = newContainer()
thisObject.container.name = 'Panel Tab Button'
thisObject.container.initialize()
thisObject.container.isClickeable = true
thisObject.container.frame.containerName = 'Panel Tab Button'
/* Lets listen to our own events to react when we have a Mouse Click */
thisObject.container.eventHandler.listenToEvent('onMouseClick', buttonPressed)
/* Animation to hide the pannel */
let tabStatus = 'visible'
let visiblePosition = {}
let hiddenPosition = {}
thisObject.status = 'up'
let upPosition = {}
let downPosition = {}
let transitionPosition = {}
let onMouseClickEventSuscriptionId
return thisObject
function finalize () {
thisObject.container.eventHandler.stopListening(onMouseClickEventSuscriptionId)
thisObject.container.finalize()
thisObject.container = undefined
thisObject.fitFunction = undefined
thisObject.parentContainer = undefined
thisObject.status = undefined
upPosition = undefined
downPosition = undefined
transitionPosition = undefined
}
function initialize () {
thisObject.container.frame.width = 10
thisObject.container.frame.height = 10
var position = {
x: thisObject.parentContainer.frame.width - 15,
y: 2
x: thisObject.parentContainer.frame.width - 14,
y: 1
}
thisObject.container.frame.position = position
visiblePosition.x = thisObject.parentContainer.frame.position.x
visiblePosition.y = thisObject.parentContainer.frame.position.y
upPosition.x = thisObject.parentContainer.frame.position.x
upPosition.y = thisObject.parentContainer.frame.position.y
hiddenPosition.x = thisObject.parentContainer.frame.position.x
hiddenPosition.y = viewPort.visibleArea.bottomRight.y
downPosition.x = thisObject.parentContainer.frame.position.x
downPosition.y = canvas.chartSpace.viewport.visibleArea.bottomRight.y
transitionPosition.x = visiblePosition.x
transitionPosition.y = visiblePosition.y
transitionPosition.x = upPosition.x
transitionPosition.y = upPosition.y
/* Lets listen to our own events to react when we have a Mouse Click */
onMouseClickEventSuscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick)
isInitialized = true
}
function buttonPressed (event) {
if (tabStatus === 'visible') {
visiblePosition.x = thisObject.parentContainer.frame.position.x
visiblePosition.y = thisObject.parentContainer.frame.position.y
function setStatus (value) {
if (value === 'up' && thisObject.status === 'down') {
thisObject.status = 'going up'
}
if (value === 'down' && thisObject.status === 'up') {
thisObject.status = 'going down'
}
}
hiddenPosition.x = thisObject.parentContainer.frame.position.x
hiddenPosition.y = viewPort.visibleArea.bottomRight.y
function onMouseClick (event) {
if (thisObject.status === 'up') {
transitionPosition.x = upPosition.x
transitionPosition.y = upPosition.y
transitionPosition.x = visiblePosition.x
transitionPosition.y = visiblePosition.y
thisObject.parentContainer.isDraggeable = false
thisObject.parentContainer.isWheelable = false
tabStatus = 'going down'
thisObject.status = 'going down'
} else {
thisObject.parentContainer.isDraggeable = true
thisObject.parentContainer.isWheelable = true
tabStatus = 'going up'
transitionPosition.x = downPosition.x
transitionPosition.y = downPosition.y
thisObject.status = 'going up'
}
}
function physics () {
if (isInitialized === false) { return }
upPosition.x = thisObject.parentContainer.frame.position.x
upPosition.y = canvas.chartSpace.viewport.visibleArea.topRight.y
downPosition.x = thisObject.parentContainer.frame.position.x
downPosition.y = canvas.chartSpace.viewport.visibleArea.bottomRight.y
if (thisObject.status === 'going down') {
if (transitionPosition.y < downPosition.y) {
transitionPosition.y = transitionPosition.y + 50
thisObject.parentContainer.frame.position.y = transitionPosition.y
} else {
thisObject.parentContainer.frame.position.y = downPosition.y
thisObject.status = 'down'
}
}
if (thisObject.status === 'going up') {
if (transitionPosition.y > upPosition.y) {
transitionPosition.y = transitionPosition.y - 50
thisObject.parentContainer.frame.position.y = transitionPosition.y
} else {
thisObject.parentContainer.frame.position.y = upPosition.y
thisObject.status = 'up'
}
}
}
@@ -82,29 +125,10 @@ function newPanelTabButton () {
if (isInitialized === false) { return }
drawButton()
if (tabStatus === 'going down') {
if (transitionPosition.y < hiddenPosition.y) {
transitionPosition.y = transitionPosition.y + 50
thisObject.parentContainer.frame.position.y = transitionPosition.y
} else {
thisObject.parentContainer.frame.position.y = hiddenPosition.y
tabStatus = 'hidden'
}
}
if (tabStatus === 'going up') {
if (transitionPosition.y > visiblePosition.y) {
transitionPosition.y = transitionPosition.y - 50
thisObject.parentContainer.frame.position.y = transitionPosition.y
} else {
thisObject.parentContainer.frame.position.y = visiblePosition.y
tabStatus = 'visible'
}
}
}
function getContainer (point) {
var container
let container
/* First we check if thisObject point is inside thisObject space. */
@@ -124,21 +148,21 @@ function newPanelTabButton () {
let point2
let point3
switch (tabStatus) {
case 'visible': {
switch (thisObject.status) {
case 'up': {
point1 = {
x: 3,
y: 3
}
point2 = {
x: container.frame.width - 3,
x: thisObject.container.frame.width - 3,
y: 3
}
point3 = {
x: container.frame.width / 2,
y: container.frame.height - 3
x: thisObject.container.frame.width / 2,
y: thisObject.container.frame.height - 3
}
break
}
@@ -150,13 +174,13 @@ function newPanelTabButton () {
}
point2 = {
x: container.frame.width - 4,
x: thisObject.container.frame.width - 4,
y: 4
}
point3 = {
x: container.frame.width / 2,
y: container.frame.height - 4
x: thisObject.container.frame.width / 2,
y: thisObject.container.frame.height - 4
}
break
}
@@ -164,34 +188,34 @@ function newPanelTabButton () {
case 'going up': {
point1 = {
x: 4,
y: container.frame.height - 4
y: thisObject.container.frame.height - 4
}
point2 = {
x: container.frame.width - 4,
y: container.frame.height - 4
x: thisObject.container.frame.width - 4,
y: thisObject.container.frame.height - 4
}
point3 = {
x: container.frame.width / 2,
x: thisObject.container.frame.width / 2,
y: 4
}
break
}
case 'hidden': {
case 'down': {
point1 = {
x: 3,
y: container.frame.height - 3
y: thisObject.container.frame.height - 3
}
point2 = {
x: container.frame.width - 3,
y: container.frame.height - 3
x: thisObject.container.frame.width - 3,
y: thisObject.container.frame.height - 3
}
point3 = {
x: container.frame.width / 2,
x: thisObject.container.frame.width / 2,
y: 3
}
break
+83
View File
@@ -0,0 +1,83 @@
function newPanelsVisibleButton () {
let thisObject = {
container: undefined,
fitFunction: undefined,
parentContainer: undefined,
panels: undefined,
showPanels: true,
draw: draw,
getContainer: getContainer, // returns the inner most container that holds the point received by parameter.
initialize: initialize,
finalize: finalize
}
/* Cointainer stuff */
thisObject.container = newContainer()
thisObject.container.name = 'Panels Visible Button'
thisObject.container.initialize()
thisObject.container.isClickeable = true
thisObject.container.frame.containerName = 'Panels Visible Button'
let onMouseClickEventSuscriptionId
return thisObject
function finalize () {
thisObject.container.eventHandler.stopListening(onMouseClickEventSuscriptionId)
thisObject.container.finalize()
thisObject.container = undefined
thisObject.fitFunction = undefined
thisObject.parentContainer = undefined
thisObject.panels = undefined
}
function initialize (panels) {
thisObject.panels = panels
setPanelVisibility()
thisObject.container.frame.width = 25
thisObject.container.frame.height = 25
let position = {
x: thisObject.container.frame.width * 1 / 8,
y: 45
}
thisObject.container.frame.position = position
/* Lets listen to our own events to react when we have a Mouse Click */
onMouseClickEventSuscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick)
}
function onMouseClick (event) {
if (thisObject.showPanels === false) {
thisObject.showPanels = true
} else {
thisObject.showPanels = false
}
setPanelVisibility()
}
function setPanelVisibility () {
for (let i = 0; i < thisObject.panels.length; i++) {
panel = canvas.panelsSpace.getPanel(thisObject.panels[i])
panel.isVisible = thisObject.showPanels
}
}
function getContainer (point) {
if (thisObject.container.frame.isThisPointHere(point, true) === true) {
return thisObject.container
}
}
function draw () {
let icon
if (thisObject.showPanels === true) {
icon = canvas.designerSpace.iconCollection.get('plotter-panel')
} else {
icon = canvas.designerSpace.iconCollection.get('social-bot')
}
drawIcon(icon, 1 / 2, 1 / 2, 0, 0, 14, thisObject.container)
}
}
+25 -12
View File
@@ -8,18 +8,17 @@ function newPlotterPanel () {
let thisObject = {
fitFunction: undefined,
onRecordChange: onRecordChange,
container: undefined,
isVisible: true,
onRecordChange: onRecordChange,
draw: draw,
getContainer: getContainer,
initialize: initialize
initialize: initialize,
finalize: finalize
}
let container = newContainer()
container.initialize()
thisObject.container = container
container.frame.containerName = 'Plotter Panel'
thisObject.container = newContainer()
thisObject.container.initialize('Plotter Panel')
let heightFactor = 1
let currentRecord
@@ -28,15 +27,28 @@ function newPlotterPanel () {
return thisObject
function finalize () {
thisObject.container.finalize()
thisObject.container = undefined
thisObject.fitFunction = undefined
thisObject.isVisible = undefined
heightFactor = undefined
currentRecord = undefined
panelTabButton.finalize()
panelTabButton = undefined
panelNode = undefined
}
function initialize (pPanelNode) {
panelNode = pPanelNode
container.frame.containerName = panelNode.name
thisObject.container.frame.containerName = panelNode.name
thisObject.container.frame.width = UI_PANEL.WIDTH.NORMAL
thisObject.container.frame.height = UI_PANEL.HEIGHT.NORMAL
thisObject.container.frame.position.x = viewPort.visibleArea.topRight.x - thisObject.container.frame.width - thisObject.container.frame.width * Math.random() * 8
thisObject.container.frame.position.y = viewPort.visibleArea.bottomLeft.y - thisObject.container.frame.height - thisObject.container.frame.height * Math.random() * 1.5
thisObject.container.frame.position.x = canvas.chartSpace.viewport.visibleArea.topRight.x - thisObject.container.frame.width - thisObject.container.frame.width * Math.random() * 8
thisObject.container.frame.position.y = canvas.chartSpace.viewport.visibleArea.bottomLeft.y - thisObject.container.frame.height - thisObject.container.frame.height * Math.random() * 1.5
panelTabButton = newPanelTabButton()
panelTabButton.parentContainer = thisObject.container
@@ -46,6 +58,7 @@ function newPlotterPanel () {
}
function getContainer (point) {
if (thisObject.isVisible !== true) { return }
let container
container = panelTabButton.getContainer(point)
@@ -70,10 +83,10 @@ function newPlotterPanel () {
}
function draw () {
if (thisObject.isVisible !== true) { return }
thisObject.container.frame.draw(false, false, true, thisObject.fitFunction)
plotCurrentRecordData()
panelTabButton.draw()
}
-967
View File
@@ -1,967 +0,0 @@
function newProductCard () {
const MODULE_NAME = 'Product Card'
const ERROR_LOG = true
const logger = newWebDebugLog()
logger.fileName = MODULE_NAME
let thisObject = {
container: undefined,
status: PRODUCT_CARD_STATUS.OFF,
devTeam: undefined,
bot: undefined,
product: undefined,
code: undefined,
fitFunction: undefined,
draw: draw,
turnOff: turnOff,
turnOn: turnOn,
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,
finalize: finalize
}
let LOADING_FILL_STYLE = 'rgba(234, 143, 23, @Opacity)'
let LOADED_FILL_STYLE = 'rgba(45, 232, 28, @Opacity)'
let UNLOADED_FILL_STYLE = 'rgba(226, 226, 226, @Opacity)'
let LOADING_STROKE_STYLE = 'rgba(234, 143, 23, @Opacity)'
let LOADED_STROKE_STYLE = 'rgba(150, 150, 150, @Opacity)'
let UNLOADED_STROKE_STYLE = 'rgba(226, 226, 226, @Opacity)'
let marketFileProgressBar = {
value: 0,
animatedValue: 0,
fillStyle: UNLOADED_FILL_STYLE,
strokeStyle: UNLOADED_STROKE_STYLE,
opacity: 0.00
}
let dailyFileProgressBar = {
value: 0,
animatedValue: 0,
fillStyle: UNLOADED_FILL_STYLE,
strokeStyle: UNLOADED_STROKE_STYLE,
opacity: 0.00
}
let singleFileProgressBar = {
value: 0,
animatedValue: 0,
fillStyle: UNLOADED_FILL_STYLE,
strokeStyle: UNLOADED_STROKE_STYLE,
opacity: 0.00
}
let fileSequenceProgressBar = {
value: 0,
animatedValue: 0,
fillStyle: UNLOADED_FILL_STYLE,
strokeStyle: UNLOADED_STROKE_STYLE,
opacity: 0.00
}
let timePeriod = INITIAL_TIME_PERIOD
let datetime = NEW_SESSION_INITIAL_DATE
/* TODO We are in a transition period in which bots and teams images might be located at different places.
What we are going to do then is to try to load them from both places and use the variable that finally gets an
image. */
/* This is the legacy image storage. */
let legacyTeamAvatar
let legacyTeamAvatarLoaded = false
/* TODO Temporary code */
let legacyBotAvatar
let legacyBotAvatarLoaded = false
/* Now the plotters images */
let legacyPlotterBanner
let legacyPlotterBannerLoaded = false
/* We are transitioning towards this */
let teamAvatar // stores the avatar image of the team the bot portrayed at this card belongs to.
let teamAvatarLoaded = false
/* TODO Temporary code */
let botAvatar // stores the avatar image of the team the bot portrayed at this card belongs to.
let botAvatarLoaded = false
/* Add an Event Handler */
thisObject.eventHandler = newEventHandler()
let imagesLoaded = 0
let lastMouseOver = 0 // This variable is used to animate what happens while we are having a mounse over.
return thisObject
function finalize () {
thisObject.container.finalize()
thisObject.eventHandler.finalize()
thisObject.container = undefined
thisObject.eventHandler = undefined
thisObject.status = undefined
thisObject.devTeam = undefined
thisObject.bot = undefined
thisObject.product = undefined
thisObject.code = undefined
thisObject.fitFunction = undefined
legacyTeamAvatar = undefined
legacyTeamAvatarLoaded = undefined
legacyBotAvatar = undefined
legacyBotAvatarLoaded = undefined
legacyPlotterBanner = undefined
timePeriod = undefined
datetime = undefined
LOADING_FILL_STYLE = undefined
LOADED_FILL_STYLE = undefined
UNLOADED_FILL_STYLE = undefined
LOADING_STROKE_STYLE = undefined
LOADED_STROKE_STYLE = undefined
UNLOADED_STROKE_STYLE = undefined
marketFileProgressBar = undefined
dailyFileProgressBar = undefined
singleFileProgressBar = undefined
fileSequenceProgressBar = undefined
}
function initialize () {
/* Create this objects continer */
try {
thisObject.container = newContainer()
thisObject.container.initialize(MODULE_NAME + thisObject.code)
thisObject.container.detectMouseOver = true
thisObject.container.isDraggeable = false
thisObject.container.isClickeable = true
/* Add information that will later be needed. */
let team = ecosystem.getTeam(thisObject.product.plotter.devTeam)
let plotter
if (team !== undefined) {
plotter = ecosystem.getPlotter(team, thisObject.product.plotter.codeName)
}
if (plotter !== undefined) {
let plotterModule = ecosystem.getPlotterModule(plotter, thisObject.product.plotter.moduleName)
thisObject.product.plotter.profilePicture = plotterModule.profilePicture
thisObject.product.plotter.module = plotterModule
}
/* Lets set the basic dimensions of this thisObject. */
var position = {
x: 0,
y: 0
}
thisObject.container.frame.position = position
thisObject.container.frame.width = UI_PANEL.WIDTH.LARGE - 20
thisObject.container.frame.height = 100
/* We retrieve the locally stored status of the Product */
let storedValue = window.localStorage.getItem(thisObject.code)
if (storedValue !== null) {
thisObject.status = storedValue
if (thisObject.status === PRODUCT_CARD_STATUS.ON) {
changeStatusTo(PRODUCT_CARD_STATUS.LOADING)
}
} else {
/*
This happens the first time the app is run on a new browser.
We will start with all product off, except for the candles chart, since something needs to be shown and allow the user to position themselves
on the timeline.
For the time being, we will hard-code the name of the bot we will turn on by default, since we dont see that change in the near future.
*/
const DEFAULT_ON_PRODUCT = 'Poloniex-BTC/USDT-AAMasters-AAOlivia-Candles'
if (thisObject.code === DEFAULT_ON_PRODUCT) {
changeStatusTo(PRODUCT_CARD_STATUS.LOADING)
} else {
changeStatusTo(PRODUCT_CARD_STATUS.OFF)
}
}
/* Lets listen to our own events to react when we have a Mouse Click */
thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick)
thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver)
/* WARNING THIS IS TEMPORARY CODE */
const LEGACY_TEAM = thisObject.devTeam.codeName
const REPO = thisObject.bot.repo
const PROFILE_PIC = thisObject.bot.profilePicture
/* The plotter banner, comes from the Legacy Location so far, no matter if the Team is at the Teams Modules or not. */
const PLOTTER_TEAM = thisObject.product.plotter.devTeam
const PLOTTER_REPO = thisObject.product.plotter.codeName
const PLOTTER_PROFILE_PIC = thisObject.product.plotter.profilePicture
legacyPlotterBanner = new Image()
legacyPlotterBanner.onload = onLegacyPlotterBanner
function onLegacyPlotterBanner () {
legacyPlotterBannerLoaded = true
}
if (PLOTTER_PROFILE_PIC !== undefined) {
legacyPlotterBanner.src = window.canvasApp.urlPrefix + 'Images/' + PLOTTER_TEAM + '/' + PLOTTER_REPO + '/' + PLOTTER_PROFILE_PIC
} else {
if (thisObject.product.plotter.banner !== undefined) {
legacyPlotterBanner.src = window.canvasApp.urlPrefix + 'Images/' + thisObject.product.plotter.banner + '-Banner.PNG'
} else {
legacyPlotterBanner.src = window.canvasApp.urlPrefix + 'Images/' + 'Default-Banner.PNG'
}
}
const TEAM = thisObject.devTeam.codeName.toLowerCase()
const BOT = thisObject.bot.codeName.toLowerCase()
if (window.canvasApp.context.teamProfileImages.get(TEAM) === undefined) {
// This means this Team is a Lecay Team, still not at any Module.
/*
Here we will download the images still at the legacy storage.
*/
legacyTeamAvatar = new Image()
legacyTeamAvatar.onload = onLegacyImageLoad
function onLegacyImageLoad () {
legacyTeamAvatarLoaded = true
}
legacyTeamAvatar.src = window.canvasApp.urlPrefix + 'Images/' + LEGACY_TEAM + '/' + LEGACY_TEAM + '.png'
legacyBotAvatar = new Image()
legacyBotAvatar.onload = onLegacyImageLoadBot
function onLegacyImageLoadBot () {
legacyBotAvatarLoaded = true
thisObject.bot.avatar = legacyBotAvatar
}
legacyBotAvatar.src = window.canvasApp.urlPrefix + 'Images/' + LEGACY_TEAM + '/' + REPO + '/' + PROFILE_PIC
} else {
/*
Here we will download the images of teams shareed at the Teams Module.
There might be Product Cards of bots beloging to teams not present currently at the Teams Module, in those cases
nothing should happen.
*/
teamAvatar = new Image()
teamAvatar.onload = onImageLoad
function onImageLoad () {
teamAvatarLoaded = true
}
teamAvatar.src = window.canvasApp.context.teamProfileImages.get(TEAM)
botAvatar = new Image()
botAvatar.onload = onImageLoadBot
function onImageLoadBot () {
botAvatarLoaded = true
thisObject.bot.avatar = botAvatar
}
botAvatar.src = window.canvasApp.context.fbProfileImages.get(TEAM + '-' + BOT)
}
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> err = ' + err.stack) }
}
}
function getContainer (point) {
var container
/* First we check if this point is inside this space. */
if (thisObject.container.frame.isThisPointHere(point, true) === true) {
return thisObject.container
} else {
/* This point does not belong to this space. */
return undefined
}
}
function setDatetime (pDatetime) {
/*
When the datetime changes from one day to another, this forces cursors to potentially load more files, thus we reset this counter and
get ready to receive events on files loaded.
*/
let currentDate = Math.trunc(datetime.valueOf() / ONE_DAY_IN_MILISECONDS)
let newDate = Math.trunc(pDatetime.valueOf() / ONE_DAY_IN_MILISECONDS)
datetime = pDatetime
if (currentDate !== newDate) {
if (timePeriod <= _1_HOUR_IN_MILISECONDS) {
dailyFileProgressBar.animatedValue = 0
}
}
}
function setTimePeriod (pTimePeriod) {
/*
When the time period below or equal to 1 hour changes, this forces cursors to potentially load more files, thus we reset this counter and
get ready to receive events on files loaded.
*/
if (timePeriod !== pTimePeriod) {
timePeriod = pTimePeriod
if (timePeriod <= _1_HOUR_IN_MILISECONDS) {
dailyFileProgressBar.animatedValue = 0
}
}
}
function onMarketFileLoaded (event) {
marketFileProgressBar.value = Math.trunc(event.totalValue * 100 / event.totalValue)
marketFileProgressBar.fillStyle = LOADING_FILL_STYLE
marketFileProgressBar.strokeStyle = LOADING_STROKE_STYLE
if (marketFileProgressBar.value > 100) { marketFileProgressBar.value = 100 }
}
function onDailyFileLoaded (event) {
dailyFileProgressBar.value = Math.trunc(event.currentValue * 100 / event.totalValue)
dailyFileProgressBar.fillStyle = LOADING_FILL_STYLE
dailyFileProgressBar.strokeStyle = LOADING_STROKE_STYLE
if (dailyFileProgressBar.value > 100) { dailyFileProgressBar.value = 100 }
}
function onSingleFileLoaded (event) {
singleFileProgressBar.value = Math.trunc(event.currentValue * 100 / event.totalValue)
singleFileProgressBar.fillStyle = LOADING_FILL_STYLE
singleFileProgressBar.strokeStyle = LOADING_STROKE_STYLE
if (singleFileProgressBar.value > 100) { singleFileProgressBar.value = 100 }
}
function onFileSequenceLoaded (event) {
fileSequenceProgressBar.value = Math.trunc(event.currentValue * 100 / event.totalValue)
fileSequenceProgressBar.fillStyle = LOADING_FILL_STYLE
fileSequenceProgressBar.strokeStyle = LOADING_STROKE_STYLE
if (fileSequenceProgressBar.value > 100) { fileSequenceProgressBar.value = 100 }
}
function turnOff () {
if (thisObject.status !== PRODUCT_CARD_STATUS.OFF) {
resetProgressBars()
changeStatusTo(PRODUCT_CARD_STATUS.OFF)
}
}
function turnOn () {
if (thisObject.status === PRODUCT_CARD_STATUS.OFF) {
changeStatusTo(PRODUCT_CARD_STATUS.LOADING)
}
}
function onMouseClick (event) {
switch (thisObject.status) {
case PRODUCT_CARD_STATUS.ON:
resetProgressBars()
changeStatusTo(PRODUCT_CARD_STATUS.OFF)
break
case PRODUCT_CARD_STATUS.OFF:
changeStatusTo(PRODUCT_CARD_STATUS.LOADING)
break
case PRODUCT_CARD_STATUS.LOADING:
changeStatusTo(PRODUCT_CARD_STATUS.OFF)
break
}
}
function resetProgressBars () {
marketFileProgressBar.animatedValue = 0
marketFileProgressBar.value = 0
marketFileProgressBar.fillStyle = UNLOADED_FILL_STYLE
marketFileProgressBar.strokeStyle = UNLOADED_STROKE_STYLE
dailyFileProgressBar.animatedValue = 0
dailyFileProgressBar.value = 0
dailyFileProgressBar.fillStyle = UNLOADED_FILL_STYLE
dailyFileProgressBar.strokeStyle = UNLOADED_STROKE_STYLE
singleFileProgressBar.animatedValue = 0
singleFileProgressBar.value = 0
singleFileProgressBar.fillStyle = UNLOADED_FILL_STYLE
singleFileProgressBar.strokeStyle = UNLOADED_STROKE_STYLE
fileSequenceProgressBar.animatedValue = 0
fileSequenceProgressBar.value = 0
fileSequenceProgressBar.fillStyle = UNLOADED_FILL_STYLE
fileSequenceProgressBar.strokeStyle = UNLOADED_STROKE_STYLE
}
function onMouseOver (event) {
lastMouseOver = 25
}
function changeStatusTo (pNewStatus) {
if (thisObject.status !== pNewStatus) {
thisObject.status = pNewStatus
let eventData = thisObject
thisObject.container.eventHandler.raiseEvent('Status Changed', eventData)
window.localStorage.setItem(thisObject.code, thisObject.status)
}
}
function draw () {
drawProductCard()
}
function drawProductCard () {
/*
Put images on the card.
*/
let fitImagePoint = {
x: 0,
y: 0
}
const devTeamImageSize = 20
const botImageSize = 20
const plotterImageSize = {
width: 180,
height: 50
}
lastMouseOver-- // Animating the mouse onMouseOver
if (lastMouseOver > 0) {
/* First the Dev Team Profile Picture. */
let teamImagePoint = {
x: 2,
y: thisObject.container.frame.height / 2 - devTeamImageSize / 2
}
teamImagePoint = thisObject.container.frame.frameThisPoint(teamImagePoint)
fitImagePoint = thisObject.fitFunction(teamImagePoint)
let teamImage
if (legacyTeamAvatarLoaded === true) {
teamImage = legacyTeamAvatar
}
if (teamAvatarLoaded === true) {
teamImage = teamAvatar
}
if (teamImage !== undefined && teamImagePoint.y === fitImagePoint.y) {
if (teamImage.naturalHeight !== 0) {
/* The image is rounded before being displayed. */
browserCanvasContext.save()
browserCanvasContext.beginPath()
browserCanvasContext.arc(teamImagePoint.x + devTeamImageSize / 2, teamImagePoint.y + devTeamImageSize / 2, devTeamImageSize / 2, 0, Math.PI * 2, true)
browserCanvasContext.closePath()
browserCanvasContext.clip()
browserCanvasContext.drawImage(teamImage, teamImagePoint.x, teamImagePoint.y, devTeamImageSize, devTeamImageSize)
browserCanvasContext.beginPath()
browserCanvasContext.arc(teamImagePoint.x, teamImagePoint.y, devTeamImageSize / 2, 0, Math.PI * 2, true)
browserCanvasContext.clip()
browserCanvasContext.closePath()
browserCanvasContext.restore()
}
}
/* Second the Bot's Profile Picture. */
if (thisObject.bot.profilePicture !== undefined) {
let botImagePoint = {
x: thisObject.container.frame.width - botImageSize / 2 - 8,
y: thisObject.container.frame.height / 2 - botImageSize / 2
}
botImagePoint = thisObject.container.frame.frameThisPoint(botImagePoint)
fitImagePoint = thisObject.fitFunction(botImagePoint)
let imageId = thisObject.bot.devTeam + '.' + thisObject.bot.profilePicture
/* TODO Temporary code */
let botImage
botImage = thisObject.bot.avatar
if (botImage !== undefined && botImagePoint.y === fitImagePoint.y) {
if (botImage.naturalHeight !== 0) {
/* The image is rounded before being displayed. */
browserCanvasContext.save()
browserCanvasContext.beginPath()
browserCanvasContext.arc(botImagePoint.x + botImageSize / 2, botImagePoint.y + botImageSize / 2, botImageSize / 2, 0, Math.PI * 2, true)
browserCanvasContext.closePath()
browserCanvasContext.clip()
browserCanvasContext.drawImage(botImage, botImagePoint.x, botImagePoint.y, botImageSize, botImageSize)
browserCanvasContext.beginPath()
browserCanvasContext.arc(botImagePoint.x, botImagePoint.y, botImageSize / 2, 0, Math.PI * 2, true)
browserCanvasContext.clip()
browserCanvasContext.closePath()
browserCanvasContext.restore()
}
}
}
}
/* Third the Plotter's Profile Picture. */
if (thisObject.product.plotter.profilePicture !== undefined || thisObject.product.plotter.legacy === false) {
let plotterImagePoint = {
x: thisObject.container.frame.width / 2 - plotterImageSize.width / 2,
y: thisObject.container.frame.height / 2 - plotterImageSize.height / 2
}
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 && plotterImagePoint.y + plotterImageSize.height === fitImagePoint.y) {
if (plotterImage.naturalHeight !== 0) {
browserCanvasContext.drawImage(plotterImage, plotterImagePoint.x, plotterImagePoint.y, plotterImageSize.width, plotterImageSize.height)
}
}
}
drawProductLoadStatus()
function drawProductLoadStatus () {
let offFillStyle = 'rgba(' + UI_COLOR.RED + ', 0.20)'
let onFillStyle = 'rgba(' + UI_COLOR.GREEN + ', 0.20)'
let loadingFillStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', 0.40)'
switch (thisObject.status) {
case PRODUCT_CARD_STATUS.ON:
browserCanvasContext.fillStyle = onFillStyle
break
case PRODUCT_CARD_STATUS.OFF:
browserCanvasContext.fillStyle = offFillStyle
break
case PRODUCT_CARD_STATUS.LOADING:
browserCanvasContext.fillStyle = loadingFillStyle
break
}
let centerPoint = {
x: thisObject.container.frame.width / 2,
y: thisObject.container.frame.height / 2 - 13
}
let point1 = {
x: centerPoint.x - plotterImageSize.width / 2,
y: centerPoint.y - plotterImageSize.height / 2 - 7
}
let point2 = {
x: centerPoint.x + plotterImageSize.width / 2,
y: centerPoint.y - plotterImageSize.height / 2 - 7
}
let point3 = {
x: centerPoint.x + plotterImageSize.width / 2,
y: centerPoint.y - plotterImageSize.height / 2 + 7
}
let point4 = {
x: centerPoint.x - plotterImageSize.width / 2,
y: centerPoint.y - plotterImageSize.height / 2 + 7
}
/* Now the transformations. */
point1 = thisObject.container.frame.frameThisPoint(point1)
point2 = thisObject.container.frame.frameThisPoint(point2)
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)
browserCanvasContext.lineTo(point3.x, point3.y)
browserCanvasContext.lineTo(point4.x, point4.y)
browserCanvasContext.closePath()
browserCanvasContext.fill()
browserCanvasContext.strokeStyle = 'rgba(150, 150, 150, 1)'
browserCanvasContext.lineWidth = 0.1
browserCanvasContext.stroke()
}
/*
print the text
*/
let labelPoint
let fontSize = 10
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
let label
if (lastMouseOver > 0) {
/* devTeam */
label = thisObject.devTeam.displayName
if (label.length > 10) { label = label.substring(1, 8) + '...' }
labelPoint = {
x: 2 + devTeamImageSize / 2 - label.length / 2 * fontSize * FONT_ASPECT_RATIO,
y: thisObject.container.frame.height / 2 + devTeamImageSize / 2 + fontSize * FONT_ASPECT_RATIO + 5
}
labelPoint = thisObject.container.frame.frameThisPoint(labelPoint)
labelPoint = thisObject.fitFunction(labelPoint)
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
browserCanvasContext.fillStyle = 'rgba(60, 60, 60, 0.50)'
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y)
/* bot */
label = thisObject.bot.displayName
if (label.length > 10) { label = label.substring(1, 8) + '...' }
labelPoint = {
x: thisObject.container.frame.width - 8 - label.length / 2 * fontSize * FONT_ASPECT_RATIO,
y: thisObject.container.frame.height / 2 + devTeamImageSize / 2 + fontSize * FONT_ASPECT_RATIO + 5
}
labelPoint = thisObject.container.frame.frameThisPoint(labelPoint)
labelPoint = thisObject.fitFunction(labelPoint)
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
browserCanvasContext.fillStyle = 'rgba(60, 60, 60, 0.50)'
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y)
}
/* product */
fontSize = 10
label = thisObject.product.displayName
if (thisObject.session !== undefined) {
const MAX_LABEL_LENGTH = 20
if (thisObject.session.name.length > MAX_LABEL_LENGTH) {
label = thisObject.session.name.substring(0, MAX_LABEL_LENGTH) + '...' + ' - ' + label
} else {
label = thisObject.session.name + ' - ' + label
}
}
labelPoint = {
x: 65,
y: thisObject.container.frame.height / 2 + 15
}
labelPoint = {
x: thisObject.container.frame.width / 2 - label.length / 2 * fontSize * FONT_ASPECT_RATIO,
y: thisObject.container.frame.height / 2 - devTeamImageSize / 2 - fontSize * FONT_ASPECT_RATIO - 20
}
labelPoint = thisObject.container.frame.frameThisPoint(labelPoint)
labelPoint = thisObject.fitFunction(labelPoint)
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
browserCanvasContext.fillStyle = 'rgba(60, 60, 60, 1)'
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y)
/* ------------------- Progress Bars -------------------------- */
const ANIMATED_INCREMENT = 5
const OPACITY_INCREMENT = 0.05
const OPACITY_MIN = 0.1
let point1
let point2
let point3
let point4
/* We draw here the Market Progress Bar. */
/* Animate */
if (marketFileProgressBar.animatedValue < marketFileProgressBar.value) {
marketFileProgressBar.animatedValue = marketFileProgressBar.animatedValue + ANIMATED_INCREMENT
marketFileProgressBar.opacity = marketFileProgressBar.opacity + OPACITY_INCREMENT
}
if (marketFileProgressBar.animatedValue >= 100) {
marketFileProgressBar.animatedValue = 100
marketFileProgressBar.opacity = marketFileProgressBar.opacity - OPACITY_INCREMENT
if (marketFileProgressBar.opacity < OPACITY_MIN) { marketFileProgressBar.opacity = OPACITY_MIN }
marketFileProgressBar.fillStyle = LOADED_FILL_STYLE.replace('@Opacity', marketFileProgressBar.opacity.toString())
marketFileProgressBar.strokeStyle = LOADED_STROKE_STYLE.replace('@Opacity', marketFileProgressBar.opacity.toString())
changeStatusTo(PRODUCT_CARD_STATUS.ON)
}
point1 = {
x: 0,
y: thisObject.container.frame.height - 1
}
point2 = {
x: thisObject.container.frame.width * marketFileProgressBar.animatedValue / 100,
y: thisObject.container.frame.height - 1
}
point3 = {
x: thisObject.container.frame.width * marketFileProgressBar.animatedValue / 100,
y: thisObject.container.frame.height - 3
}
point4 = {
x: 0,
y: thisObject.container.frame.height - 3
}
/* Now the transformations. */
point1 = thisObject.container.frame.frameThisPoint(point1)
point2 = thisObject.container.frame.frameThisPoint(point2)
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)
browserCanvasContext.lineTo(point3.x, point3.y)
browserCanvasContext.lineTo(point4.x, point4.y)
browserCanvasContext.closePath()
browserCanvasContext.fillStyle = marketFileProgressBar.fillStyle.replace('@Opacity', marketFileProgressBar.opacity.toString())
browserCanvasContext.strokeStyle = marketFileProgressBar.strokeStyle.replace('@Opacity', marketFileProgressBar.opacity.toString())
browserCanvasContext.fill()
browserCanvasContext.lineWidth = 0.1
browserCanvasContext.stroke()
/* We draw here the Daily Progress Bar. */
/* Animate */
if (dailyFileProgressBar.animatedValue < dailyFileProgressBar.value) {
dailyFileProgressBar.animatedValue = dailyFileProgressBar.animatedValue + ANIMATED_INCREMENT
dailyFileProgressBar.opacity = dailyFileProgressBar.opacity + OPACITY_INCREMENT
}
if (dailyFileProgressBar.animatedValue >= 100) {
dailyFileProgressBar.animatedValue = 100
dailyFileProgressBar.opacity = dailyFileProgressBar.opacity - OPACITY_INCREMENT
if (dailyFileProgressBar.opacity < OPACITY_MIN) { dailyFileProgressBar.opacity = OPACITY_MIN }
dailyFileProgressBar.fillStyle = LOADED_FILL_STYLE.replace('@Opacity', dailyFileProgressBar.opacity.toString())
dailyFileProgressBar.strokeStyle = LOADED_STROKE_STYLE.replace('@Opacity', dailyFileProgressBar.opacity.toString())
changeStatusTo(PRODUCT_CARD_STATUS.ON)
}
point1 = {
x: 0,
y: thisObject.container.frame.height - 4
}
point2 = {
x: thisObject.container.frame.width * dailyFileProgressBar.animatedValue / 100,
y: thisObject.container.frame.height - 4
}
point3 = {
x: thisObject.container.frame.width * dailyFileProgressBar.animatedValue / 100,
y: thisObject.container.frame.height - 6
}
point4 = {
x: 0,
y: thisObject.container.frame.height - 6
}
/* Now the transformations. */
point1 = thisObject.container.frame.frameThisPoint(point1)
point2 = thisObject.container.frame.frameThisPoint(point2)
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)
browserCanvasContext.lineTo(point3.x, point3.y)
browserCanvasContext.lineTo(point4.x, point4.y)
browserCanvasContext.closePath()
browserCanvasContext.fillStyle = dailyFileProgressBar.fillStyle.replace('@Opacity', dailyFileProgressBar.opacity.toString())
browserCanvasContext.strokeStyle = dailyFileProgressBar.strokeStyle.replace('@Opacity', dailyFileProgressBar.opacity.toString())
browserCanvasContext.fill()
browserCanvasContext.lineWidth = 0.1
browserCanvasContext.stroke()
/* We draw here the Single File Progress Bar. */
/* Animate */
if (singleFileProgressBar.animatedValue < singleFileProgressBar.value) {
singleFileProgressBar.animatedValue = singleFileProgressBar.animatedValue + ANIMATED_INCREMENT
singleFileProgressBar.opacity = singleFileProgressBar.opacity + OPACITY_INCREMENT
}
if (singleFileProgressBar.animatedValue >= 100) {
singleFileProgressBar.animatedValue = 100
singleFileProgressBar.opacity = singleFileProgressBar.opacity - OPACITY_INCREMENT
if (singleFileProgressBar.opacity < OPACITY_MIN) { singleFileProgressBar.opacity = OPACITY_MIN }
singleFileProgressBar.fillStyle = LOADED_FILL_STYLE.replace('@Opacity', singleFileProgressBar.opacity.toString())
singleFileProgressBar.strokeStyle = LOADED_STROKE_STYLE.replace('@Opacity', singleFileProgressBar.opacity.toString())
changeStatusTo(PRODUCT_CARD_STATUS.ON)
}
point1 = {
x: 0,
y: thisObject.container.frame.height - 7
}
point2 = {
x: thisObject.container.frame.width * singleFileProgressBar.animatedValue / 100,
y: thisObject.container.frame.height - 7
}
point3 = {
x: thisObject.container.frame.width * singleFileProgressBar.animatedValue / 100,
y: thisObject.container.frame.height - 9
}
point4 = {
x: 0,
y: thisObject.container.frame.height - 9
}
/* Now the transformations. */
point1 = thisObject.container.frame.frameThisPoint(point1)
point2 = thisObject.container.frame.frameThisPoint(point2)
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)
browserCanvasContext.lineTo(point3.x, point3.y)
browserCanvasContext.lineTo(point4.x, point4.y)
browserCanvasContext.closePath()
browserCanvasContext.fillStyle = singleFileProgressBar.fillStyle.replace('@Opacity', singleFileProgressBar.opacity.toString())
browserCanvasContext.strokeStyle = singleFileProgressBar.strokeStyle.replace('@Opacity', singleFileProgressBar.opacity.toString())
browserCanvasContext.fill()
browserCanvasContext.lineWidth = 0.1
browserCanvasContext.stroke()
/* We draw here the File Sequence Progress Bar. */
/* Animate */
if (fileSequenceProgressBar.animatedValue < fileSequenceProgressBar.value) {
fileSequenceProgressBar.animatedValue = fileSequenceProgressBar.animatedValue + ANIMATED_INCREMENT
fileSequenceProgressBar.opacity = fileSequenceProgressBar.opacity + OPACITY_INCREMENT
}
if (fileSequenceProgressBar.animatedValue >= 100) {
fileSequenceProgressBar.animatedValue = 100
fileSequenceProgressBar.opacity = fileSequenceProgressBar.opacity - OPACITY_INCREMENT
if (fileSequenceProgressBar.opacity < OPACITY_MIN) { fileSequenceProgressBar.opacity = OPACITY_MIN }
fileSequenceProgressBar.fillStyle = LOADED_FILL_STYLE.replace('@Opacity', fileSequenceProgressBar.opacity.toString())
fileSequenceProgressBar.strokeStyle = LOADED_STROKE_STYLE.replace('@Opacity', fileSequenceProgressBar.opacity.toString())
changeStatusTo(PRODUCT_CARD_STATUS.ON)
}
point1 = {
x: 0,
y: thisObject.container.frame.height - 10
}
point2 = {
x: thisObject.container.frame.width * fileSequenceProgressBar.animatedValue / 100,
y: thisObject.container.frame.height - 10
}
point3 = {
x: thisObject.container.frame.width * fileSequenceProgressBar.animatedValue / 100,
y: thisObject.container.frame.height - 11
}
point4 = {
x: 0,
y: thisObject.container.frame.height - 11
}
/* Now the transformations. */
point1 = thisObject.container.frame.frameThisPoint(point1)
point2 = thisObject.container.frame.frameThisPoint(point2)
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)
browserCanvasContext.lineTo(point3.x, point3.y)
browserCanvasContext.lineTo(point4.x, point4.y)
browserCanvasContext.closePath()
browserCanvasContext.fillStyle = fileSequenceProgressBar.fillStyle.replace('@Opacity', fileSequenceProgressBar.opacity.toString())
browserCanvasContext.strokeStyle = fileSequenceProgressBar.strokeStyle.replace('@Opacity', fileSequenceProgressBar.opacity.toString())
browserCanvasContext.fill()
browserCanvasContext.lineWidth = 0.1
browserCanvasContext.stroke()
}
}
-506
View File
@@ -1,506 +0,0 @@
function newProductsPanel () {
let thisObject = {
name: 'Products Panel',
fitFunction: undefined,
container: undefined,
productCards: [],
getLoadingProductCards: getLoadingProductCards,
physics: physics,
draw: draw,
getContainer: getContainer, // returns the inner most container that holds the point received by parameter.
initialize: initialize
}
/* Cointainer stuff */
let container = newContainer()
container.initialize()
container.isDraggeable = true
container.isWheelable = true
thisObject.container = container
let isInitialized = false
let cardsMap = new Map()
let visibleProductCards = []
let firstVisibleCard = 1
/* Needed Variables */
const CANRD_SEPARATION = 5
let panelTabButton
let exchange
let market
return thisObject
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 = UI_PANEL.HEIGHT.LARGE * 1.5 // viewPort.visibleArea.bottomLeft.y - viewPort.visibleArea.topLeft.y // UI_PANEL.HEIGHT.LARGE;
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
panelTabButton = newPanelTabButton()
panelTabButton.parentContainer = thisObject.container
panelTabButton.container.frame.parentFrame = thisObject.container.frame
panelTabButton.fitFunction = thisObject.fitFunction
panelTabButton.initialize()
/* First thing is to build the thisObject.productCards array */
let ecosystem = JSON.parse(window.localStorage.getItem('ecosystem'))
if (ecosystem === null || ecosystem === undefined) {
ecosystem = getUserEcosystem()
}
/* For legacy plotters, we will add product cards based on the old ecosystem file */
for (let i = 0; i < ecosystem.devTeams.length; i++) {
let devTeam = ecosystem.devTeams[i]
for (let j = 0; j < devTeam.bots.length; j++) {
let bot = devTeam.bots[j]
if (bot.type !== 'Indicator Bot Instance') { continue }
if (bot.products !== undefined) {
for (let k = 0; k < bot.products.length; k++) {
let product = bot.products[k]
addProductCard(devTeam, bot, product)
}
}
}
}
/* For new plotters defined at the UI, we will add product cards based on what we find at the workspace */
let workspaceNode = canvas.designerSpace.workspace.workspaceNode
for (let i = 0; i < workspaceNode.rootNodes.length; i++) {
let rootNode = workspaceNode.rootNodes[i]
if (rootNode.type === 'Team') {
let teamNode = rootNode
let team = {}
if (teamNode.code === undefined) { continue }
try {
let code = JSON.parse(teamNode.code)
team.codeName = code.codeName
} catch (err) {
continue
}
for (let j = 0; j < teamNode.indicatorBots.length; j++) {
let botNode = teamNode.indicatorBots[j]
let bot = {}
if (botNode.code === undefined) { continue }
try {
let code = JSON.parse(botNode.code)
bot.codeName = code.codeName
} catch (err) {
continue
}
for (let k = 0; k < botNode.products.length; k++) {
let productNode = botNode.products[k]
let product = {}
if (productNode.code === undefined) { continue }
try {
let code = JSON.parse(productNode.code)
product.codeName = code.codeName
} catch (err) {
continue
}
if (productNode.payload.referenceParent === undefined) { continue }
let plotterModuleNode = productNode.payload.referenceParent
let plotterModule = {}
if (plotterModuleNode.code === undefined) { continue }
try {
let code = JSON.parse(plotterModuleNode.code)
plotterModule.codeName = code.codeName
plotterModule.banner = code.banner
} catch (err) {
continue
}
if (plotterModuleNode.payload.parentNode === undefined) { continue }
let plotterNode = plotterModuleNode.payload.parentNode
let plotter = {}
if (plotterNode.code === undefined) { continue }
try {
let code = JSON.parse(plotterNode.code)
plotter.codeName = code.codeName
} catch (err) {
continue
}
if (plotterNode.payload.parentNode === undefined) { continue }
let plotterTeamNode = plotterNode.payload.parentNode
let plotterTeam = {}
if (plotterTeamNode.code === undefined) { continue }
try {
let code = JSON.parse(plotterTeamNode.code)
plotterTeam.codeName = code.codeName
} catch (err) {
continue
}
/* Conversion to fit old format */
product.plotter = plotter
product.plotter.devTeam = plotterTeam.codeName
product.plotter.moduleName = plotterModule.codeName
product.plotter.banner = plotterModule.banner
product.plotter.legacy = false
product.plotter.module = { panels: [] }
product.displayName = productNode.name
product.dataSets = []
product.exchangeList = [{'name': 'Poloniex'}]
product.node = productNode
team.displayName = teamNode.name
team.host = {'url': 'localhost'}
bot.displayName = botNode.name
for (let m = 0; m < productNode.datasets.length; m++) {
let dataset = productNode.datasets[m]
if (dataset.code === undefined) { continue }
try {
let code = JSON.parse(dataset.code)
product.dataSets.push(code)
} catch (err) {
continue
}
}
addProductCard(team, bot, product)
}
}
}
}
thisObject.container.eventHandler.listenToEvent('onMouseWheel', onMouseWheel)
isInitialized = true
}
function removeProductCard (code) {
let productCard = cardsMap.get(code)
cardsMap.delete(code)
productCard.turnOff()
productCard.finalize()
}
function addProductCard (devTeam, bot, product, session) {
/* Now we create Product objects */
let productCard = newProductCard()
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
if (session !== undefined) {
productCard.code = productCard.code + '-' + session.id
}
productCard.session = session
/* Initialize it */
productCard.initialize()
cardsMap.set(productCard.code, productCard)
/* 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
/* 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 + productCard.container.frame.height * thisObject.productCards.length + CANRD_SEPARATION
/* Add to the Product Array */
thisObject.productCards.push(productCard)
/* Add to Visible Product Array */
if (productCard.container.frame.position.y + productCard.container.frame.height < thisObject.container.frame.height) {
visibleProductCards.push(productCard)
}
/* Listen to Status Changes Events */
productCard.container.eventHandler.listenToEvent('Status Changed', onProductCardStatusChanged)
productCard.container.eventHandler.listenToEvent('onMouseWheel', onMouseWheel)
return productCard
}
function onMouseWheel (event) {
delta = event.wheelDelta
if (delta > 0) {
delta = -1
} else {
delta = 1
}
firstVisibleCard = firstVisibleCard + delta
calculateVisbleProductCards()
}
function calculateVisbleProductCards () {
let availableSlots = visibleProductCards.length
if (firstVisibleCard < 1) { firstVisibleCard = 1 }
if (firstVisibleCard > (thisObject.productCards.length - availableSlots + 1)) { firstVisibleCard = thisObject.productCards.length - availableSlots + 1 }
visibleProductCards = []
for (let i = 0; i < thisObject.productCards.length; i++) {
if (i + 1 >= firstVisibleCard && i + 1 < firstVisibleCard + availableSlots) {
let productCard = thisObject.productCards[i]
/* 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 + productCard.container.frame.height * visibleProductCards.length + CANRD_SEPARATION
/* Add to Visible Product Array */
visibleProductCards.push(productCard)
}
}
}
function onProductCardStatusChanged (pProductCard) {
thisObject.container.eventHandler.raiseEvent('Product Card Status Changed', pProductCard)
}
function getLoadingProductCards () {
/* Returns all thisObject.productCards which status is LOADING */
let onProducts = []
for (let i = 0; i < thisObject.productCards.length; i++) {
if (thisObject.productCards[i].status === PRODUCT_CARD_STATUS.LOADING) {
onProducts.push(thisObject.productCards[i])
}
}
return onProducts
}
function getContainer (point) {
let container
container = panelTabButton.getContainer(point)
if (container !== undefined) { return container }
/* 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 */
for (let i = 0; i < visibleProductCards.length; i++) {
container = visibleProductCards[i].getContainer(point)
if (container !== undefined) {
let checkPoint = {
x: point.x,
y: point.y
}
checkPoint = thisObject.fitFunction(checkPoint)
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. */
let checkPoint = {
x: point.x,
y: point.y
}
checkPoint = thisObject.fitFunction(checkPoint)
if (point.x === checkPoint.x && point.y === checkPoint.y) {
return thisObject.container
}
}
}
function physics () {
if (isInitialized === false) { return }
/*
The overall idea here is that we need to keep syncronized the panel with the layers that are
defined at the Designer. Users can connect or disconnect any objext resulting in changes in which
are valid layers and which not at any point in time. So what we do here is trying to keep the panel
only with the layers that are connected to each Definition structure.
To achieve this, first we are going to move all session related cards to a local array. Then we are
going to check for layers at the designer, and will move back the cards which still have layers well
defined to where they were.
If we find new layers we will add them at that point. Finally, the cards that still remain at the
local array after all the layers at the designer have been processed, are turned off and discarded.
*/
let localProductCards = []
moveToLocalProductCards()
synchronizeLayersAndProductCards()
/* At this poins all the cards still at the local array need to be removed from the panel. */
turnOffUnusedProducCards()
calculateVisbleProductCards()
function synchronizeLayersAndProductCards () {
/* We will look into the ecosystem to know which Trading bots are defined there. */
let ecosystem = JSON.parse(window.localStorage.getItem('ecosystem'))
if (ecosystem === null || ecosystem === undefined) {
ecosystem = getUserEcosystem()
}
/* Then we get an Array of all instances of this bot placed at Definitions on the Workspace. */
let tradingBotInstances = canvas.designerSpace.workspace.getAllTradingBotInstances()
/* Here we will go through all the instances of trading engines and see their layers, to see
if we can find a matching layer. */
for (let n = 0; n < tradingBotInstances.length; n++) {
let tradingBotInstance = tradingBotInstances[n]
let code
let instanceBot
let instanceTeam
for (let m = 0; m < tradingBotInstance.processes.length; m++) {
let process = tradingBotInstance.processes[m]
try {
code = JSON.parse(process.payload.referenceParent.payload.parentNode.code)
instanceBot = code.codeName
code = JSON.parse(process.payload.referenceParent.payload.parentNode.payload.parentNode.code)
instanceTeam = code.codeName
} catch (err) {
continue
}
for (let i = 0; i < ecosystem.devTeams.length; i++) {
let devTeam = ecosystem.devTeams[i]
for (let j = 0; j < devTeam.bots.length; j++) {
let bot = devTeam.bots[j]
if (bot.type !== 'Trading Bot Instance') { continue }
if (devTeam.codeName === instanceTeam && bot.codeName === instanceBot) {
/* We found an instance of the same Trading we are currently looking at.
Next thing to do is to see its layers to see if we can match it with the current product. */
if (process.session !== undefined) {
if (process.session.layerManager !== undefined) {
let layerManager = process.session.layerManager
if (layerManager.payload.floatingObject.isCollapsed !== true) {
if (bot.products !== undefined) {
for (let k = 0; k < bot.products.length; k++) {
let product = bot.products[k]
for (let p = 0; p < layerManager.layers.length; p++) {
let layer = layerManager.layers[p]
let layerCode
try {
layerCode = JSON.parse(layer.code)
} catch (err) {
// if we can not parse this, then we ignore this trading engine.
}
if (product.codeName === layerCode.product) {
/* We have a layer that is matching the current product */
let cardCode = exchange + '-' + market.assetB + '/' + market.assetA + '-' + devTeam.codeName + '-' + bot.codeName + '-' + product.codeName + '-' + process.session.id
let cardFound = removeFromLocalProductCards(cardCode)
if (cardFound !== true) {
productCard = addProductCard(devTeam, bot, product, process.session)
onProductCardStatusChanged(productCard)
}
}
}
}
}
}
}
}
}
}
}
}
}
}
function moveToLocalProductCards () {
removeNext()
function removeNext () {
for (let i = 0; i < thisObject.productCards.length; i++) {
let productCard = thisObject.productCards[i]
if (productCard.session !== undefined) {
thisObject.productCards.splice(i, 1)
localProductCards.push(productCard)
removeNext()
}
}
}
}
function removeFromLocalProductCards (code) {
for (let i = 0; i < localProductCards.length; i++) {
let productCard = localProductCards[i]
if (productCard.code === code) {
thisObject.productCards.push(productCard)
localProductCards.splice(i, 1)
return true
}
}
}
function turnOffUnusedProducCards () {
for (let i = 0; i < localProductCards.length; i++) {
let productCard = localProductCards[i]
removeProductCard(productCard.code)
}
}
}
function draw () {
if (isInitialized === false) { return }
thisObject.container.frame.draw(false, false, true, thisObject.fitFunction)
for (let i = 0; i < visibleProductCards.length; i++) {
visibleProductCards[i].draw()
}
panelTabButton.draw()
}
}
-160
View File
@@ -1,160 +0,0 @@

function newTimeControlPanel () {
let thisObject = {
container: undefined,
setDatetime: setDatetime,
datetimeDisplay: undefined,
stepDisplay: undefined,
draw: draw,
getContainer: getContainer, // returns the inner most container that holds the point received by parameter.
initialize: initialize
}
let container = newContainer()
container.initialize()
container.isDraggeable = true
thisObject.container = container
thisObject.container.frame.containerName = 'Current Datetime'
let timePeriod
let panelTabButton
return thisObject
function initialize () {
thisObject.container.frame.width = UI_PANEL.WIDTH.SMALL
thisObject.container.frame.height = UI_PANEL.HEIGHT.SMALL
let position = {
x: (viewPort.visibleArea.topRight.x - viewPort.visibleArea.topLeft.x) / 2 - thisObject.container.frame.width / 2,
y: viewPort.visibleArea.bottomLeft.y - thisObject.container.frame.height
}
thisObject.container.frame.position = position
panelTabButton = newPanelTabButton()
panelTabButton.parentContainer = thisObject.container
panelTabButton.container.frame.parentFrame = thisObject.container.frame
panelTabButton.initialize()
let datetime = NEW_SESSION_INITIAL_DATE
let datetimeDisplay = {
currentDatetime: datetime,
addTime: addTime,
draw: drawTimeDisplay
}
thisObject.datetimeDisplay = datetimeDisplay
viewPort.eventHandler.listenToEvent('Zoom Changed', onZoomChanged)
timePeriod = INITIAL_TIME_PERIOD
}
function onBotChangedTime (pNewDatetime) {
let newDatetime = new Date(pNewDatetime)
thisObject.container.eventHandler.raiseEvent('Datetime Changed', newDatetime)
}
function onZoomChanged (event) {
if (event !== undefined) { // it is undefined when the level is just being animated.
timePeriod = recalculatePeriod(event.newLevel)
}
}
function getContainer (point) {
let container
container = panelTabButton.getContainer(point)
if (container !== undefined) { return container }
/* First we check if thisObject point is inside thisObject space. */
if (thisObject.container.frame.isThisPointHere(point, true) === true) {
/* 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. */
return undefined
}
}
function setDatetime (pDatetime) {
thisObject.datetimeDisplay.currentDatetime = new Date(pDatetime)
}
function addTime (seconds) {
let newDate = thisObject.datetimeDisplay.currentDatetime
newDate.setSeconds(newDate.getSeconds() + seconds)
thisObject.datetimeDisplay.currentDatetime = newDate
}
function draw () {
return
thisObject.container.frame.draw(false, false, true)
thisObject.datetimeDisplay.draw()
panelTabButton.draw()
}
function drawTimeDisplay () {
let fontSize = 10
let label = thisObject.datetimeDisplay.currentDatetime.toUTCString()
let labelArray = label.split(' ')
label = labelArray[0] + ' ' + labelArray[1] + ' ' + labelArray[2] + ' ' + labelArray[3]
/* Now we transform x on the actual coordinate on the canvas. */
let labelPoint = {
x: thisObject.container.frame.width / 2 - label.length / 2 * fontSize * FONT_ASPECT_RATIO,
y: thisObject.container.frame.height * 4.4 / 10
}
labelPoint = thisObject.container.frame.frameThisPoint(labelPoint)
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
browserCanvasContext.fillStyle = 'rgba(60, 60, 60, 0.50)'
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y)
/* The time */
label = labelArray[4] + ' ' + labelArray[5]
/* Now we transform x on the actual coordinate on the canvas. */
labelPoint = {
x: thisObject.container.frame.width / 2 - label.length / 2 * fontSize * FONT_ASPECT_RATIO,
y: thisObject.container.frame.height * 6.5 / 10
}
labelPoint = thisObject.container.frame.frameThisPoint(labelPoint)
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
browserCanvasContext.fillStyle = 'rgba(60, 60, 60, 0.50)'
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y)
if (timePeriod > _45_MINUTES_IN_MILISECONDS) {
label = timePeriod / _1_HOUR_IN_MILISECONDS + ' hs'
} else {
label = timePeriod / _1_MINUTE_IN_MILISECONDS + ' min'
}
/* Now we transform x on the actual coordinate on the canvas. */
labelPoint = {
x: thisObject.container.frame.width / 2 - label.length / 2 * fontSize * FONT_ASPECT_RATIO,
y: thisObject.container.frame.height * 8.5 / 10
}
labelPoint = thisObject.container.frame.frameThisPoint(labelPoint)
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
browserCanvasContext.fillStyle = 'rgba(60, 60, 60, 0.50)'
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y)
}
}
+116 -106
View File
@@ -6,40 +6,30 @@ function newPlotter () {
logger.fileName = MODULE_NAME
let thisObject = {
/* Events declared outside the plotter. */
currentRecord: undefined,
container: undefined,
onDailyFileLoaded: onDailyFileLoaded,
// Main functions and properties.
initialize: initialize,
finalize: finalize,
container: undefined,
getContainer: getContainer,
setTimePeriod: setTimePeriod,
setTimeFrame: setTimeFrame,
setDatetime: setDatetime,
recalculateScale: recalculateScale,
draw: draw,
// Secondary functions and properties.
currentRecord: undefined // ---> Check Here
setCoordinateSystem: setCoordinateSystem,
draw: draw
}
let container = newContainer()
container.initialize()
thisObject.container = container
let timeLineCoordinateSystem = newTimeLineCoordinateSystem() // Needed to be able to plot on the timeline.
let slotCoordinateSystem // Needed to be able to plot on a slot over the timeline.
let coordinateSystem
let plotterModuleConfig
let slotHeight = (viewPort.visibleArea.bottomRight.y - viewPort.visibleArea.topLeft.y) / 10 // This is the amount of slots available
let slotHeight = (canvas.chartSpace.viewport.visibleArea.bottomRight.y - canvas.chartSpace.viewport.visibleArea.topLeft.y) / 10 // This is the amount of slots available
let mustRecalculateDataPoints = false
let atMousePositionFillStyles = new Map()
let atMousePositionStrokeStyles = new Map()
let timePeriod // This will hold the current Time Period the user is at.
let timeFrame // This will hold the current Time Frame the user is at.
let datetime // This will hold the current Datetime the user is at.
let marketFile // This is the current Market File being plotted.
@@ -51,13 +41,17 @@ function newPlotter () {
let productDefinition // Here we store a snapshot of the product definition which references this plotter.
let records = [] // We will have the information to be plotted here.
let userPositionDate
let onMouseOverEventSuscriptionId
let zoomChangedEventSubscriptionId
let offsetChangedEventSubscriptionId
let dragFinishedEventSubscriptionId
let dimmensionsChangedEventSubscriptionId
let marketFilesUpdatedEventSubscriptionId
let dailyFilesUpdatedEventSubscriptionId
let onDisplaceEventSubscriptionId
let scaleChangedEventSubscriptionId
let logged = false
return thisObject
@@ -65,25 +59,27 @@ function newPlotter () {
function finalize () {
try {
/* Stop listening to the necesary events. */
viewPort.eventHandler.stopListening(zoomChangedEventSubscriptionId)
viewPort.eventHandler.stopListening(offsetChangedEventSubscriptionId)
thisObject.container.eventHandler.stopListening(onMouseOverEventSuscriptionId)
canvas.chartSpace.viewport.eventHandler.stopListening(zoomChangedEventSubscriptionId)
canvas.chartSpace.viewport.eventHandler.stopListening(offsetChangedEventSubscriptionId)
canvas.eventHandler.stopListening(dragFinishedEventSubscriptionId)
thisObject.container.eventHandler.stopListening(dimmensionsChangedEventSubscriptionId)
marketFiles.eventHandler.stopListening(marketFilesUpdatedEventSubscriptionId)
dailyFiles.eventHandler.stopListening(dailyFilesUpdatedEventSubscriptionId)
thisObject.container.eventHandler.stopListening(onDisplaceEventSubscriptionId)
/* Clear References */
marketFiles = undefined
dailyFiles = undefined
datetime = undefined
timePeriod = undefined
timeFrame = undefined
marketFile = undefined
fileCursor = undefined
timeLineCoordinateSystem = undefined
slotCoordinateSystem = undefined
finalizeCoordinateSystem()
coordinateSystem = undefined
plotterModuleConfig = undefined
slotHeight = undefined
mustRecalculateDataPoints = undefined
@@ -94,37 +90,38 @@ function newPlotter () {
}
}
function initialize (pStorage, pExchange, pMarket, pDatetime, pTimePeriod, callBackFunction, pProductDefinition) {
function initialize (pStorage, pDatetime, pTimeFrame, pCoordinateSystem, callBackFunction, pProductDefinition) {
try {
/* Store the information received. */
marketFiles = pStorage.marketFiles[0]
dailyFiles = pStorage.dailyFiles[0]
datetime = pDatetime
timePeriod = pTimePeriod
timeFrame = pTimeFrame
coordinateSystem = pCoordinateSystem
initializeCoordinateSystem()
productDefinition = pProductDefinition
/* We need a Market File in order to calculate the Y scale, since this scale depends on actual data. */
marketFile = marketFiles.getFile(ONE_DAY_IN_MILISECONDS) // This file is the one processed faster.
recalculateScale()
/* Now we set the right files according to current Period. */
marketFile = marketFiles.getFile(pTimePeriod)
fileCursor = dailyFiles.getFileCursor(pTimePeriod)
marketFile = marketFiles.getFile(pTimeFrame)
fileCursor = dailyFiles.getFileCursor(pTimeFrame)
/* Listen to the necesary events. */
zoomChangedEventSubscriptionId = viewPort.eventHandler.listenToEvent('Zoom Changed', onZoomChanged)
offsetChangedEventSubscriptionId = viewPort.eventHandler.listenToEvent('Offset Changed', onOffsetChanged)
zoomChangedEventSubscriptionId = canvas.chartSpace.viewport.eventHandler.listenToEvent('Zoom Changed', onViewportZoomChanged)
offsetChangedEventSubscriptionId = canvas.chartSpace.viewport.eventHandler.listenToEvent('Position Changed', onViewportPositionChanged)
dragFinishedEventSubscriptionId = canvas.eventHandler.listenToEvent('Drag Finished', onDragFinished)
marketFilesUpdatedEventSubscriptionId = marketFiles.eventHandler.listenToEvent('Files Updated', onMarketFilesUpdated)
dailyFilesUpdatedEventSubscriptionId = dailyFiles.eventHandler.listenToEvent('Files Updated', onDailyFilesUpdated)
onDisplaceEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onDisplace', onDisplace)
onMouseOverEventSuscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver)
/* Get ready for plotting. */
recalculate()
dimmensionsChangedEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('Dimmensions Changed', function () {
recalculateScale()
recalculate()
})
@@ -135,9 +132,27 @@ function newPlotter () {
}
}
function initializeCoordinateSystem () {
scaleChangedEventSubscriptionId = coordinateSystem.eventHandler.listenToEvent('Scale Changed', onScaleChanged)
}
function finalizeCoordinateSystem () {
coordinateSystem.eventHandler.stopListening(scaleChangedEventSubscriptionId)
}
function onScaleChanged () {
mustRecalculateDataPoints = true
recalculate()
}
function onMouseOver (event) {
let userPosition = getDateFromPoint(event, thisObject.container, coordinateSystem)
userPositionDate = userPosition.valueOf()
}
function onMarketFilesUpdated () {
try {
let newMarketFile = marketFiles.getFile(timePeriod)
let newMarketFile = marketFiles.getFile(timeFrame)
if (newMarketFile !== undefined) {
marketFile = newMarketFile
mustRecalculateDataPoints = true
@@ -150,7 +165,7 @@ function newPlotter () {
function onDailyFilesUpdated () {
try {
let newFileCursor = dailyFiles.getFileCursor(timePeriod)
let newFileCursor = dailyFiles.getFileCursor(timeFrame)
if (newFileCursor !== undefined) {
fileCursor = newFileCursor
mustRecalculateDataPoints = true
@@ -165,8 +180,8 @@ function newPlotter () {
try {
let container
/* First we check if this point is inside this space. */
if (this.container.frame.isThisPointHere(point) === true) {
return this.container
if (thisObject.container.frame.isThisPointHere(point) === true) {
return thisObject.container
} else {
/* This point does not belong to this space. */
return undefined
@@ -176,20 +191,20 @@ function newPlotter () {
}
}
function setTimePeriod (pTimePeriod) {
function setTimeFrame (pTimeFrame) {
try {
if (timePeriod !== pTimePeriod) {
timePeriod = pTimePeriod
if (timeFrame !== pTimeFrame) {
timeFrame = pTimeFrame
mustRecalculateDataPoints = true
if (timePeriod >= _1_HOUR_IN_MILISECONDS) {
let newMarketFile = marketFiles.getFile(pTimePeriod)
if (timeFrame >= _1_HOUR_IN_MILISECONDS) {
let newMarketFile = marketFiles.getFile(pTimeFrame)
if (newMarketFile !== undefined) {
marketFile = newMarketFile
recalculate()
}
} else {
let newFileCursor = dailyFiles.getFileCursor(pTimePeriod)
let newFileCursor = dailyFiles.getFileCursor(pTimeFrame)
if (newFileCursor !== undefined) {
fileCursor = newFileCursor
@@ -198,7 +213,7 @@ function newPlotter () {
}
}
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] setTimePeriod -> err = ' + err.stack) }
if (ERROR_LOG === true) { logger.write('[ERROR] setTimeFrame -> err = ' + err.stack) }
}
}
@@ -206,6 +221,12 @@ function newPlotter () {
datetime = pDatetime
}
function setCoordinateSystem (pCoordinateSystem) {
finalizeCoordinateSystem()
coordinateSystem = pCoordinateSystem
initializeCoordinateSystem()
}
function onDailyFileLoaded (event) {
try {
if (event.currentValue === event.totalValue) {
@@ -219,7 +240,7 @@ function newPlotter () {
function draw () {
try {
this.container.frame.draw()
thisObject.container.frame.draw()
plotChart()
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] draw -> err = ' + err.stack) }
@@ -228,7 +249,7 @@ function newPlotter () {
function recalculate () {
try {
if (timePeriod >= _1_HOUR_IN_MILISECONDS) {
if (timeFrame >= _1_HOUR_IN_MILISECONDS) {
recalculateUsingMarketFiles()
} else {
recalculateUsingDailyFiles()
@@ -257,7 +278,10 @@ function newPlotter () {
}
}
if (record.begin >= farLeftDate.valueOf() && record.end <= farRightDate.valueOf()) {
if (
(record.begin >= farLeftDate.valueOf() && record.end <= farRightDate.valueOf()) &&
(record.end >= coordinateSystem.min.x && record.begin <= coordinateSystem.max.x)
) {
record.previous = previous
jsonifiedArray.push(record)
previous = record
@@ -272,14 +296,14 @@ function newPlotter () {
return jsonifiedArray
}
function calculationsProcedure (jsonArray, recordDefinition, calculationsProcedure, timePeriod) {
function calculationsProcedure (jsonArray, recordDefinition, calculationsProcedure, timeFrame) {
/*
This function has as an input an array of JSON objects, and it adds calculated properties to
complete the set of properties that will be available.
*/
let system = { // These are the available system variables to be used in User Code and Formulas
timePeriod: timePeriod,
timeFrame: timeFrame,
ONE_DAY_IN_MILISECONDS: ONE_DAY_IN_MILISECONDS
}
let variable = {} // This is the structure where the user will define its own variables that will be shared across different code blocks and formulas.
@@ -348,10 +372,10 @@ function newPlotter () {
if (fileCursor === undefined) { return } // We need to wait until there is a fileCursor
if (fileCursor.files.size === 0) { return } // We need to wait until there are files in the cursor
let daysOnSides = getSideDays(timePeriod)
let daysOnSides = getSideDays(timeFrame)
let leftDate = getDateFromPoint(viewPort.visibleArea.topLeft, thisObject.container, timeLineCoordinateSystem)
let rightDate = getDateFromPoint(viewPort.visibleArea.topRight, thisObject.container, timeLineCoordinateSystem)
let leftDate = getDateFromPoint(canvas.chartSpace.viewport.visibleArea.topLeft, thisObject.container, coordinateSystem)
let rightDate = getDateFromPoint(canvas.chartSpace.viewport.visibleArea.topRight, thisObject.container, coordinateSystem)
let dateDiff = rightDate.valueOf() - leftDate.valueOf()
@@ -373,7 +397,7 @@ function newPlotter () {
/* Add the calculated properties */
if (productDefinition.calculations !== undefined) {
let calculationsResult = calculationsProcedure(jsonData, productDefinition.record, productDefinition.calculations, timePeriod)
let calculationsResult = calculationsProcedure(jsonData, productDefinition.record, productDefinition.calculations, timeFrame)
records.push(...calculationsResult) // This adds records to the current array.
} else {
records.push(...jsonData)// This adds records to the current array.
@@ -401,10 +425,10 @@ function newPlotter () {
try {
if (marketFile === undefined) { return } // Initialization not complete yet.
let daysOnSides = getSideDays(timePeriod)
let daysOnSides = getSideDays(timeFrame)
let leftDate = getDateFromPoint(viewPort.visibleArea.topLeft, thisObject.container, timeLineCoordinateSystem)
let rightDate = getDateFromPoint(viewPort.visibleArea.topRight, thisObject.container, timeLineCoordinateSystem)
let leftDate = getDateFromPoint(canvas.chartSpace.viewport.visibleArea.topLeft, thisObject.container, coordinateSystem)
let rightDate = getDateFromPoint(canvas.chartSpace.viewport.visibleArea.topRight, thisObject.container, coordinateSystem)
let dateDiff = rightDate.valueOf() - leftDate.valueOf()
@@ -426,7 +450,7 @@ function newPlotter () {
/* Add the calculated properties */
if (productDefinition.calculations !== undefined) {
let calculationsResult = calculationsProcedure(jsonData, productDefinition.record, productDefinition.calculations, timePeriod)
let calculationsResult = calculationsProcedure(jsonData, productDefinition.record, productDefinition.calculations, timeFrame)
records.push(...calculationsResult) // This adds records to the current array.
} else {
records.push(...jsonData)// This adds records to the current array.
@@ -438,7 +462,7 @@ function newPlotter () {
function recalculateScale () {
try {
if (timeLineCoordinateSystem.maxValue > 0) { return } // Already calculated.
if (coordinateSystem.maxValue > 0) { return } // Already calculated.
/* First we calculate the default scale */
let minValue = {
x: MIN_PLOTABLE_DATE.valueOf(),
@@ -447,32 +471,15 @@ function newPlotter () {
let maxValue = {
x: MAX_PLOTABLE_DATE.valueOf(),
y: nextPorwerOf10(USDT_BTC_HTH) / 4 // TODO: This 4 is temporary
y: nextPorwerOf10(MAX_DEFAULT_RATE_SCALE_VALUE) / 4 // TODO: This 4 is temporary
}
timeLineCoordinateSystem.initialize(
coordinateSystem.initialize(
minValue,
maxValue,
thisObject.container.frame.width,
thisObject.container.frame.height
)
/* In case the plotter is configured to a certain slot, we calculate the slot coordinate system too. */
if (productDefinition.referenceParent.code === undefined) { return }
plotterModuleConfig = JSON.parse(productDefinition.referenceParent.code)
if (plotterModuleConfig.slot === undefined) { return }
slotCoordinateSystem = newTimeLineCoordinateSystem()
minValue.y = plotterModuleConfig.slot.minValue
maxValue.y = plotterModuleConfig.slot.maxValue
slotCoordinateSystem.initialize(
minValue,
maxValue,
thisObject.container.frame.width,
slotHeight
)
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] recalculateScale -> err = ' + err.stack) }
}
@@ -480,9 +487,6 @@ function newPlotter () {
function plotChart () {
try {
let userPosition = getUserPosition()
let userPositionDate = userPosition.point.x
/* Clean the pannel at places where there is no record. */
let currentRecord = {
data: undefined
@@ -508,13 +512,19 @@ function newPlotter () {
y: 0
}
beginPoint = timeLineCoordinateSystem.transformThisPoint(beginPoint)
endPoint = timeLineCoordinateSystem.transformThisPoint(endPoint)
beginPoint = coordinateSystem.transformThisPoint(beginPoint)
endPoint = coordinateSystem.transformThisPoint(endPoint)
beginPoint = transformThisPoint(beginPoint, thisObject.container)
endPoint = transformThisPoint(endPoint, thisObject.container)
if (endPoint.x < viewPort.visibleArea.bottomLeft.x || beginPoint.x > viewPort.visibleArea.bottomRight.x) {
beginPoint = canvas.chartSpace.viewport.fitIntoVisibleArea(beginPoint)
endPoint = canvas.chartSpace.viewport.fitIntoVisibleArea(endPoint)
beginPoint = thisObject.fitFunction(beginPoint)
endPoint = thisObject.fitFunction(endPoint)
if (endPoint.x < canvas.chartSpace.viewport.visibleArea.bottomLeft.x || beginPoint.x > canvas.chartSpace.viewport.visibleArea.bottomRight.x) {
continue
}
@@ -562,14 +572,10 @@ function newPlotter () {
The information we store in files is independent from the charing system and its coordinate systems.
That means that the first thing we allways need to do is to trasform these points to the coordinate system of the timeline.
*/
dataPoint = timeLineCoordinateSystem.transformThisPoint(dataPoint)
/*
The browser canvas object does not care about our timeline and its coordinate system. In order to draw on a html canvas we
need the points to be converted into the canvas coordinate system.
Next we transform again to the screen coordinate system.
*/
dataPoint = coordinateSystem.transformThisPoint(dataPoint)
dataPoint = transformThisPoint(dataPoint, thisObject.container)
dataPoint = canvas.chartSpace.viewport.fitIntoVisibleArea(dataPoint)
dataPoint = thisObject.fitFunction(dataPoint)
/* Store the data point at the local map */
dataPoints.set(point.id, dataPoint)
@@ -577,7 +583,7 @@ function newPlotter () {
if (plotterModuleConfig !== undefined) {
if (plotterModuleConfig.slot !== undefined) {
/* We reset the y coordinate since it will be transformed with another coordinate system to fit into a slot. */
dataPoint.y = (-1) * y * slotCoordinateSystem.scale.y + (plotterModuleConfig.slot.number - 1) * slotHeight + viewPort.visibleArea.topLeft.y
dataPoint.y = (-1) * y * coordinateSystem.scale.y + (plotterModuleConfig.slot.number - 1) * slotHeight + canvas.chartSpace.viewport.visibleArea.topLeft.y
}
}
}
@@ -717,7 +723,7 @@ function newPlotter () {
y: dataPointObject.y
}
/* We make sure the points do not fall outside the viewport visible area. This step allways need to be done. */
dataPoint = viewPort.fitIntoVisibleArea(dataPoint)
dataPoint = canvas.chartSpace.viewport.fitIntoVisibleArea(dataPoint)
if (k === 0) {
browserCanvasContext.moveTo(dataPoint.x, dataPoint.y)
} else {
@@ -766,12 +772,12 @@ function newPlotter () {
}
}
function onZoomChanged (event) {
function onViewportZoomChanged (event) {
try {
mustRecalculateDataPoints = true
recalculate()
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] onZoomChanged -> err = ' + err.stack) }
if (ERROR_LOG === true) { logger.write('[ERROR] onViewportZoomChanged -> err = ' + err.stack) }
}
}
@@ -783,20 +789,24 @@ function newPlotter () {
}
}
function onOffsetChanged (event) {
try {
mustRecalculateDataPoints = true
if (event !== undefined) {
if (event.recalculate === true) {
recalculate()
return
}
}
if (Math.random() * 100 > 95) {
function onDisplace (event) {
recalculateAll(event)
}
function onViewportPositionChanged (event) {
recalculateAll(event)
}
function recalculateAll (event) {
mustRecalculateDataPoints = true
if (event !== undefined) {
if (event.recalculate === true) {
recalculate()
};
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] onOffsetChanged -> err = ' + err.stack) }
return
}
}
if (Math.random() * 100 > 95) {
recalculate()
}
}
}
+21 -21
View File
@@ -1,5 +1,5 @@

function newProductStorage (pName) {
function newProductStorage (name) {
const MODULE_NAME = 'Product Storage'
const ERROR_LOG = true
const logger = newWebDebugLog()
@@ -31,7 +31,7 @@ function newProductStorage (pName) {
singleFile: [],
fileSequences: [],
setDatetime: setDatetime,
setTimePeriod: setTimePeriod,
setTimeFrame: setTimeFrame,
initialize: initialize,
finalize: finalize
}
@@ -40,10 +40,10 @@ function newProductStorage (pName) {
/* We name the event Handler to easy debugging. */
thisObject.eventHandler.name = 'Storage-' + pName
thisObject.eventHandler.name = 'Storage-' + name
let datetime
let timePeriod
let timeFrame
return thisObject
@@ -74,23 +74,23 @@ function newProductStorage (pName) {
}
}
function initialize (pDevTeam, pBot, pSession, pProduct, pExchange, pMarket, pDatetime, pTimePeriod, callBackFunction) {
function initialize (dataMine, bot, session, product, exchange, market, pDatetime, pTimeFrame, callBackFunction) {
try {
datetime = pDatetime
timePeriod = pTimePeriod
timeFrame = pTimeFrame
let dataSetsToLoad = 0
let dataSetsLoaded = 0
for (let i = 0; i < pProduct.dataSets.length; i++) {
let thisSet = pProduct.dataSets[i]
for (let i = 0; i < product.datasets.length; i++) {
let dataset = product.datasets[i]
switch (thisSet.type) {
switch (dataset.code.type) {
case 'Market Files': {
dataSetsToLoad++
let marketFiles = newMarketFiles()
marketFiles.initialize(pDevTeam, pBot, pSession, pProduct, thisSet, pExchange, pMarket, onMarketFileReady)
marketFiles.initialize(dataMine, bot, session, product, dataset, exchange, market, onMarketFileReady)
thisObject.marketFiles.push(marketFiles)
}
break
@@ -99,7 +99,7 @@ function newProductStorage (pName) {
dataSetsToLoad++
let dailyFiles = newDailyFiles()
dailyFiles.initialize(pDevTeam, pBot, pSession, pProduct, thisSet, pExchange, pMarket, pDatetime, pTimePeriod, onDailyFileReady)
dailyFiles.initialize(dataMine, bot, session, product, dataset, exchange, market, pDatetime, pTimeFrame, onDailyFileReady)
thisObject.dailyFiles.push(dailyFiles)
}
break
@@ -108,7 +108,7 @@ function newProductStorage (pName) {
dataSetsToLoad++
let singleFile = newSingleFile()
singleFile.initialize(pDevTeam, pBot, pSession, pProduct, thisSet, pExchange, pMarket, onSingleFileReady)
singleFile.initialize(dataMine, bot, session, product, dataset, exchange, market, onSingleFileReady)
thisObject.singleFile.push(singleFile)
}
break
@@ -117,12 +117,12 @@ function newProductStorage (pName) {
dataSetsToLoad++
let fileSequences = newFileSequence()
fileSequences.initialize(pDevTeam, pBot, pSession, pProduct, thisSet, pExchange, pMarket, onFileSequenceReady)
fileSequences.initialize(dataMine, bot, session, product, dataset, exchange, market, onFileSequenceReady)
thisObject.fileSequences.push(fileSequences)
}
break
default:
if (ERROR_LOG === true) { logger.write('[WARN] initialize -> initialize -> dataset with no type defined. Data can not be retrieved. -> codeName = ' + thisSet.codeName) }
if (ERROR_LOG === true) { logger.write('[WARN] initialize -> dataset with no type defined or type not supported -> dataset.code.type = ' + dataset.code.type) }
}
function onMarketFileReady (err, pCaller) {
@@ -309,7 +309,7 @@ function newProductStorage (pName) {
datetime = new Date(pDatetime)
if (currentDate !== newDate) {
if (timePeriod <= _1_HOUR_IN_MILISECONDS) {
if (timeFrame <= _1_HOUR_IN_MILISECONDS) {
for (let i = 0; i < thisObject.dailyFiles.length; i++) {
thisObject.dailyFiles[i].setDatetime(pDatetime)
}
@@ -317,15 +317,15 @@ function newProductStorage (pName) {
}
}
function setTimePeriod (pTimePeriod) {
/* We are going to filter out the cases in which the timePeriod received is the same that the one we already know. */
function setTimeFrame (pTimeFrame) {
/* We are going to filter out the cases in which the timeFrame received is the same that the one we already know. */
if (timePeriod !== pTimePeriod) {
timePeriod = pTimePeriod
if (timeFrame !== pTimeFrame) {
timeFrame = pTimeFrame
if (timePeriod <= _1_HOUR_IN_MILISECONDS) {
if (timeFrame <= _1_HOUR_IN_MILISECONDS) {
for (let i = 0; i < thisObject.dailyFiles.length; i++) {
thisObject.dailyFiles[i].setTimePeriod(pTimePeriod, datetime)
thisObject.dailyFiles[i].setTimeFrame(pTimeFrame, datetime)
}
}
}
+4 -4
View File
@@ -106,7 +106,7 @@
<Compile Include="TopSpace\CurrentEvent.js">
<SubType>Code</SubType>
</Compile>
<Compile Include="TopSpace\DevTeam.js">
<Compile Include="TopSpace\dataMine.js">
<SubType>Code</SubType>
</Compile>
<Compile Include="TopSpace\EndUser.js">
@@ -127,7 +127,7 @@
<Compile Include="Spaces\PanelsSpace.js">
<SubType>Code</SubType>
</Compile>
<Compile Include="ProductCard.js">
<Compile Include="Layer.js">
<SubType>Code</SubType>
</Compile>
<Compile Include="Files\SingleFile.js">
@@ -156,9 +156,9 @@
<Compile Include="EventHandler.js" />
<Compile Include="Spaces\FloatingSpace.js" />
<Compile Include="Frame.js" />
<Compile Include="Panels\ProductsPanel.js" />
<Compile Include="Panels\LayersPanel.js" />
<Compile Include="Panels\TimeControlPanel.js" />
<Compile Include="TimeLineCoordinateSystem.js" />
<Compile Include="coordinateSystem.js" />
<Compile Include="SplashScreen.js">
<SubType>Code</SubType>
</Compile>
+1 -1
View File
@@ -1,6 +1,6 @@
# Welcome to the Canvas App
The Canvas App provides a visual environment for the _Charting System_ and the _Designer_.
The Canvas App provides a visual environment for the _Charting Space_ and the _Designer_.
**Installation (for developers):** To install the Canvas App, you need to install AAWeb, following [this guide](https://github.com/Superalgos/AAWeb/blob/develop/README.md).
+25 -36
View File
@@ -1,56 +1,45 @@
function drawScaleDisplay (label1, label2, xExtraOffSet1, xExtraOffSet2, container, fitFunction) {
let fontSize1 = 20
let fontSize2 = 10
const RED_LINE_HIGHT = 5
function drawScaleDisplay (label1, label2, label3, xExtraOffSet1, xExtraOffSet2, xExtraOffSet3, icon1, icon2, container, backgroundColor) {
const RED_LINE_HIGHT = 4
const OPACITY = 1
let params = {
cornerRadius: 3,
lineWidth: RED_LINE_HIGHT,
cornerRadius: 5,
lineWidth: 1,
container: container,
borderColor: UI_COLOR.RUSTED_RED,
castShadow: false,
backgroundColor: UI_COLOR.DARK,
opacity: OPACITY,
fitFunction: fitFunction
backgroundColor: backgroundColor,
opacity: OPACITY
}
roundedCornersBackground(params)
/* Place the Text */
let xOffset1 = label1.length * fontSize1 * FONT_ASPECT_RATIO
label1 = label1.substring(0, 18)
label2 = label2.substring(0, 20)
label3 = label3.substring(0, 20)
let labelPoint1 = {
x: container.frame.width / 2 - xOffset1 + xExtraOffSet1,
y: container.frame.height / 2 + 6
}
drawLabel(label1, 1 / 2, 92 / 100, 0, 0, 9, container)
drawLabel(label2, 1 / 2, 42 / 100, 0, 0, 17, container)
drawLabel(label3, 1 / 2, 67 / 100, 0, 0, 9, container)
labelPoint1 = container.frame.frameThisPoint(labelPoint1)
let x = labelPoint1.x
labelPoint1 = fitFunction(labelPoint1)
labelPoint1.x = x
drawIcon(icon1, 1 / 8, 1 / 2, 0, 0, 28, container)
drawIcon(icon2, 7 / 8, 1 / 2, 0, 0, 28, container)
}
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
function drawScaleDisplayCover (container) {
let params = {
cornerRadius: 5,
lineWidth: 1,
container: container,
borderColor: UI_COLOR.WHITE,
castShadow: false,
backgroundColor: UI_COLOR.WHITE,
opacity: '0.25'
}
labelPoint2 = container.frame.frameThisPoint(labelPoint2)
labelPoint2 = fitFunction(labelPoint2)
browserCanvasContext.font = fontSize2 + 'px ' + UI_FONT.PRIMARY
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', 1)'
browserCanvasContext.fillText(label2, labelPoint2.x, labelPoint2.y)
roundedCornersBackground(params)
}
+384 -55
View File
@@ -5,18 +5,34 @@ function newRateScale () {
container: undefined,
rate: undefined,
fitFunction: undefined,
visible: true,
heightPercentage: 150,
payload: undefined,
scale: undefined,
offset: undefined,
minValue: undefined,
maxValue: undefined,
isVisible: true,
layersOn: undefined,
setScale: setScale,
onMouseOverSomeTimeMachineContainer: onMouseOverSomeTimeMachineContainer,
physics: physics,
draw: draw,
drawForeground: drawForeground,
getContainer: getContainer,
initialize: initialize,
finalize: finalize
}
const HEIGHT_PERCENTAGE_DEFAULT_VALUE = 50
const STEP_SIZE = 2
const MIN_WIDTH = 50
const DEFAULT_SCALE = 50
const STEP_SCALE = 1
const MIN_SCALE = 0
const MAX_SCALE = 100
const SNAP_THRESHOLD_SCALE = 1
const DEFAULT_OFFSET = 0
const STEP_OFFSET = 1
const MIN_OFFSET = -1000
const MAX_OFFSET = 1000
const SNAP_THRESHOLD_OFFSET = 3
thisObject.container = newContainer()
thisObject.container.initialize(MODULE_NAME)
@@ -26,56 +42,167 @@ function newRateScale () {
thisObject.container.isWheelable = true
thisObject.container.detectMouseOver = true
thisObject.container.frame.width = 110
thisObject.container.frame.height = 25
thisObject.container.frame.width = UI_PANEL.WIDTH.NORMAL
thisObject.container.frame.height = 40
thisObject.offset = DEFAULT_OFFSET
let visible = true
let isMouseOver
let onMouseWheelEventSubscriptionId
let onMouseOverEventSubscriptionId
let onMouseNotOverEventSubscriptionId
let coordinateSystem
let limitingContainer
let rateCalculationsContainer
let mouse = {
position: {
x: 0,
y: 0
}
}
let offsetTimer = 0
let scaleTimer = 0
return thisObject
function finalize () {
thisObject.container.eventHandler.stopListening(onMouseWheelEventSubscriptionId)
thisObject.container.eventHandler.stopListening(onMouseOverEventSubscriptionId)
thisObject.container.eventHandler.stopListening(onMouseNotOverEventSubscriptionId)
thisObject.container.finalize()
thisObject.container = undefined
thisObject.fitFunction = undefined
thisObject.payload = undefined
coordinateSystem = undefined
limitingContainer = undefined
rateCalculationsContainer = undefined
mouse = undefined
}
function initialize () {
thisObject.container.eventHandler.listenToEvent('onMouseWheel', onMouseWheel)
thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver)
thisObject.container.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver)
function initialize (pCoordinateSystem, pLimitingContainer, pRateCalculationsContainer) {
coordinateSystem = pCoordinateSystem
limitingContainer = pLimitingContainer
rateCalculationsContainer = pRateCalculationsContainer
thisObject.heightPercentage = window.localStorage.getItem(MODULE_NAME)
if (!thisObject.heightPercentage) {
thisObject.heightPercentage = HEIGHT_PERCENTAGE_DEFAULT_VALUE
} else {
thisObject.heightPercentage = JSON.parse(thisObject.heightPercentage)
}
thisObject.minValue = coordinateSystem.min.y
thisObject.maxValue = coordinateSystem.max.y
onMouseWheelEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseWheel', onMouseWheel)
onMouseOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver)
onMouseNotOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver)
thisObject.scale = DEFAULT_SCALE
readObjectState()
let event = {}
event.heightPercentage = thisObject.heightPercentage
thisObject.container.eventHandler.raiseEvent('Height Percentage Changed', event)
event.scale = thisObject.scale
thisObject.container.eventHandler.raiseEvent('Rate Scale Value Changed', event)
}
function onMouseOver () {
function onMouseOverSomeTimeMachineContainer (event) {
if (event.containerId === undefined) {
/* This happens when the mouse over was not at the instance of a certain scale, but anywhere else. */
visible = true
} else {
if (event.containerId === thisObject.container.id) {
visible = true
} else {
visible = false
turnOnCounter = 0
}
}
mouse = {
position: {
x: event.x,
y: event.y
}
}
}
function onMouseOver (event) {
isMouseOver = true
event.containerId = thisObject.container.id
thisObject.container.eventHandler.raiseEvent('onMouseOverScale', event)
}
function onMouseNotOver () {
isMouseOver = false
offsetTimer = 0
scaleTimer = 0
}
function onMouseWheel (event) {
delta = event.wheelDelta
if (delta < 0) {
thisObject.heightPercentage = thisObject.heightPercentage - STEP_SIZE
if (thisObject.heightPercentage < STEP_SIZE) { thisObject.heightPercentage = STEP_SIZE }
} else {
thisObject.heightPercentage = thisObject.heightPercentage + STEP_SIZE
if (thisObject.heightPercentage > 150) { thisObject.heightPercentage = 200 }
}
event.heightPercentage = thisObject.heightPercentage
thisObject.container.eventHandler.raiseEvent('Height Percentage Changed', event)
let morePower = 1
let delta
window.localStorage.setItem(MODULE_NAME, thisObject.heightPercentage)
if (event.shiftKey === true) {
if (event.buttons === 4) { morePower = 10 } // Mouse wheel pressed.
delta = event.wheelDelta
if (delta < 0) {
thisObject.offset = thisObject.offset - STEP_OFFSET * morePower
if (thisObject.offset < MIN_OFFSET) { thisObject.offset = STEP_OFFSET }
} else {
thisObject.offset = thisObject.offset + STEP_OFFSET * morePower
if (thisObject.offset > MAX_OFFSET) { thisObject.offset = MAX_OFFSET }
}
if (
thisObject.offset <= DEFAULT_OFFSET + SNAP_THRESHOLD_OFFSET &&
thisObject.offset >= DEFAULT_OFFSET - SNAP_THRESHOLD_OFFSET
) {
event.offset = 0
} else {
event.offset = -thisObject.offset
}
event.isUserAction = true
thisObject.container.eventHandler.raiseEvent('Rate Scale Offset Changed', event)
saveObjectState()
offsetTimer = 100
scaleTimer = 0
} else {
if (event.buttons === 4) { morePower = 5 } // Mouse wheel pressed.
delta = event.wheelDelta
if (delta < 0) {
thisObject.scale = thisObject.scale - STEP_SCALE * morePower
if (thisObject.scale < MIN_SCALE) { thisObject.scale = MIN_SCALE }
} else {
thisObject.scale = thisObject.scale + STEP_SCALE * morePower
if (thisObject.scale > MAX_SCALE) { thisObject.scale = MAX_SCALE }
}
finishScaleChange(event)
}
}
function setScale (scale) {
thisObject.scale = scale
let event = {}
finishScaleChange(event)
}
function finishScaleChange (event) {
if (
thisObject.scale <= DEFAULT_SCALE + SNAP_THRESHOLD_SCALE &&
thisObject.scale >= DEFAULT_SCALE - SNAP_THRESHOLD_SCALE
) {
event.scale = DEFAULT_SCALE
} else {
event.scale = thisObject.scale
}
event.isUserAction = true
thisObject.container.eventHandler.raiseEvent('Rate Scale Value Changed', event)
saveObjectState()
offsetTimer = 0
scaleTimer = 100
}
function getContainer (point) {
@@ -84,18 +211,232 @@ function newRateScale () {
}
}
function physics () {
function saveObjectState () {
try {
let code = JSON.parse(thisObject.payload.node.code)
code.scale = thisObject.scale / MAX_SCALE * 100
code.scale = code.scale.toFixed(0)
code.offset = thisObject.offset
code.minValue = thisObject.minValue
code.maxValue = thisObject.maxValue
thisObject.payload.node.code = JSON.stringify(code, null, 4)
} catch (err) {
// we ignore errors here since most likely they will be parsing errors.
}
}
function readObjectState () {
try {
let code = JSON.parse(thisObject.payload.node.code)
if (isNaN(code.scale) || code.scale === null || code.scale === undefined) {
// not using this value
} else {
code.scale = code.scale / 100 * MAX_SCALE
if (code.scale < MIN_SCALE) { code.scale = MIN_SCALE }
if (code.scale > MAX_SCALE) { code.scale = MAX_SCALE }
if (code.scale !== thisObject.scale) {
thisObject.scale = code.scale
let event = {}
if (
thisObject.scale <= DEFAULT_SCALE + SNAP_THRESHOLD_SCALE &&
thisObject.scale >= DEFAULT_SCALE - SNAP_THRESHOLD_SCALE
) {
event.scale = DEFAULT_SCALE
} else {
event.scale = thisObject.scale
}
thisObject.container.eventHandler.raiseEvent('Rate Scale Value Changed', event)
}
}
if (isNaN(code.offset) || code.offset === null || code.offset === undefined) {
// not using this value
} else {
if (code.offset < MIN_OFFSET) { code.offset = MIN_OFFSET }
if (code.offset > MAX_OFFSET) { code.offset = MAX_OFFSET }
if (code.offset !== thisObject.offset) {
thisObject.offset = code.offset
let event = {}
if (
thisObject.offset <= DEFAULT_OFFSET + SNAP_THRESHOLD_OFFSET &&
thisObject.offset >= DEFAULT_OFFSET - SNAP_THRESHOLD_OFFSET
) {
event.offset = 0
} else {
event.offset = -thisObject.offset
}
thisObject.container.eventHandler.raiseEvent('Rate Scale Offset Changed', event)
}
}
if (
(isNaN(code.minValue) || code.minValue === null || code.minValue === undefined) ||
(isNaN(code.maxValue) || code.maxValue === null || code.maxValue === undefined)
) {
// not using this value
} else {
if (thisObject.minValue !== code.minValue || thisObject.maxValue !== code.maxValue) {
thisObject.minValue = code.minValue
thisObject.maxValue = code.maxValue
coordinateSystem.min.y = thisObject.minValue
coordinateSystem.max.y = thisObject.maxValue
coordinateSystem.recalculateScale()
}
}
saveObjectState() // this overrides any invalid value at the config.
} catch (err) {
// we ignore errors here since most likely they will be parsing errors.
}
}
function physics () {
offsetTimer--
scaleTimer--
readObjectState()
positioningPhysics()
}
function positioningPhysics () {
/* Container Limits */
let upCorner = {
x: 0,
y: 0
}
let bottonCorner = {
x: limitingContainer.frame.width,
y: limitingContainer.frame.height
}
upCorner = transformThisPoint(upCorner, limitingContainer)
bottonCorner = transformThisPoint(bottonCorner, limitingContainer)
upCorner = limitingContainer.fitFunction(upCorner, true)
bottonCorner = limitingContainer.fitFunction(bottonCorner, true)
/* We will check if we need to change the bottom because of being one of many scales of the same type */
let displaceFactor = 0
if (thisObject.payload.parentNode === undefined) { return } // This happens when in the process of deleting the scale, timeline chart or time machine.
if (thisObject.payload.parentNode.type === 'Timeline Chart') {
if (thisObject.payload.parentNode.payload.parentNode !== undefined) {
if (thisObject.payload.parentNode.payload.parentNode.rateScale !== undefined) {
if (thisObject.payload.parentNode.payload.parentNode.rateScale.payload.isVisible === true) {
displaceFactor++
}
}
for (let i = 0; i < thisObject.payload.parentNode.payload.parentNode.timelineCharts.length; i++) {
let timelineChart = thisObject.payload.parentNode.payload.parentNode.timelineCharts[i]
if (timelineChart.rateScale !== undefined) {
if (thisObject.payload.node.id !== timelineChart.rateScale.id) {
if (timelineChart.rateScale.payload.isVisible === true) {
displaceFactor++
}
} else {
break
}
}
}
}
}
bottonCorner.x = bottonCorner.x - thisObject.container.frame.width * displaceFactor
/* Mouse Position Rate Calculation */
let ratePoint = {
x: 0,
y: mouse.position.y + thisObject.offset
}
thisObject.rate = getRateFromPoint(ratePoint, rateCalculationsContainer, coordinateSystem)
/* rateScale Positioning */
ratePoint = {
x: limitingContainer.frame.width,
y: 0
}
ratePoint = transformThisPoint(ratePoint, limitingContainer.frame.container)
ratePoint.y = mouse.position.y - thisObject.container.frame.height / 2 + thisObject.container.frame.height
/* Checking against the container limits. */
if (ratePoint.x < upCorner.x) { ratePoint.x = upCorner.x }
if (ratePoint.x + thisObject.container.frame.width > bottonCorner.x) { ratePoint.x = bottonCorner.x }
if (ratePoint.y < upCorner.y + thisObject.container.frame.height) { ratePoint.y = upCorner.y + thisObject.container.frame.height }
if (ratePoint.y > bottonCorner.y) { ratePoint.y = bottonCorner.y }
thisObject.container.frame.position.y = ratePoint.y - thisObject.container.frame.height
thisObject.container.frame.position.x = ratePoint.x - thisObject.container.frame.width
thisObject.isVisible = true
thisObject.payload.isVisible = true
if (thisObject.container.frame.position.y + thisObject.container.frame.height * 2 > bottonCorner.y ||
thisObject.container.frame.position.y - thisObject.container.frame.height * 1 < upCorner.y ||
thisObject.container.frame.position.x < upCorner.x
) {
thisObject.isVisible = false
thisObject.payload.isVisible = false
}
if (thisObject.layersOn === 0) {
thisObject.isVisible = false
thisObject.payload.isVisible = false
}
}
function draw () {
drawRate()
drawArrows()
drawScaleBox()
if (visible === false) {
drawScaleDisplayCover(thisObject.container)
}
}
function drawForeground () {
if (isMouseOver === true) {
drawScaleBox()
drawArrows()
}
}
function drawScaleBox () {
if (thisObject.rate === undefined) { return }
let rate = thisObject.rate
if (rate < coordinateSystem.min.y) {
rate = coordinateSystem.min.y
}
if (rate > coordinateSystem.max.y) {
rate = coordinateSystem.max.y
}
let label = (rate - Math.trunc(rate)).toFixed(2)
let labelArray = label.split('.')
let label1 = thisObject.payload.node.payload.parentNode.name
let label2 = (Math.trunc(rate)).toLocaleString()
let label3 = labelArray[1]
let icon1 = canvas.designerSpace.iconByUiObjectType.get(thisObject.payload.node.payload.parentNode.type)
let icon2 = canvas.designerSpace.iconByUiObjectType.get(thisObject.payload.node.type)
let backgroundColor = UI_COLOR.BLACK
if (offsetTimer > 0) {
label2 = thisObject.offset.toFixed(0)
label3 = 'OFFSET'
}
if (scaleTimer > 0) {
label2 = (thisObject.scale / MAX_SCALE * 100).toFixed(0)
label3 = 'SCALE'
}
drawScaleDisplay(label1, label2, label3, 0, 0, 0, icon1, icon2, thisObject.container, backgroundColor)
}
function drawArrows () {
if (isMouseOver !== true) { return }
if (thisObject.visible === false || thisObject.rate === undefined) { return }
if (visible === false || thisObject.rate === undefined) { return }
const X_OFFSET = thisObject.container.frame.width / 2
const Y_OFFSET = thisObject.container.frame.height / 2
@@ -105,7 +446,7 @@ function newRateScale () {
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 CURRENT_SCALE_DISTANCE = MIN_DISTANCE_FROM_CENTER + thisObject.scale
const MAX_DISTANCE_FROM_CENTER = MIN_DISTANCE_FROM_CENTER + 215 + DISTANCE_BETWEEN_ARROWS
let ARROW_DIRECTION = 0
@@ -118,17 +459,17 @@ function newRateScale () {
function drawTwoArrows () {
point1 = {
x: X_OFFSET - WIDTH / 2,
y: Y_OFFSET + DISTANCE_BETWEEN_ARROWS / 2 * ARROW_DIRECTION + CURRENT_VALUE_DISTANCE * ARROW_DIRECTION
y: Y_OFFSET + DISTANCE_BETWEEN_ARROWS / 2 * ARROW_DIRECTION + CURRENT_SCALE_DISTANCE * ARROW_DIRECTION
}
point2 = {
x: X_OFFSET,
y: Y_OFFSET + HEIGHT * ARROW_DIRECTION + DISTANCE_BETWEEN_ARROWS / 2 * ARROW_DIRECTION + CURRENT_VALUE_DISTANCE * ARROW_DIRECTION
y: Y_OFFSET + HEIGHT * ARROW_DIRECTION + DISTANCE_BETWEEN_ARROWS / 2 * ARROW_DIRECTION + CURRENT_SCALE_DISTANCE * ARROW_DIRECTION
}
point3 = {
x: X_OFFSET + WIDTH / 2,
y: Y_OFFSET + DISTANCE_BETWEEN_ARROWS / 2 * ARROW_DIRECTION + CURRENT_VALUE_DISTANCE * ARROW_DIRECTION
y: Y_OFFSET + DISTANCE_BETWEEN_ARROWS / 2 * ARROW_DIRECTION + CURRENT_SCALE_DISTANCE * ARROW_DIRECTION
}
point1 = thisObject.container.frame.frameThisPoint(point1)
@@ -137,17 +478,17 @@ function newRateScale () {
point4 = {
x: X_OFFSET - WIDTH / 2,
y: Y_OFFSET - DISTANCE_BETWEEN_ARROWS / 2 * ARROW_DIRECTION + CURRENT_VALUE_DISTANCE * ARROW_DIRECTION
y: Y_OFFSET - DISTANCE_BETWEEN_ARROWS / 2 * ARROW_DIRECTION + CURRENT_SCALE_DISTANCE * ARROW_DIRECTION
}
point5 = {
x: X_OFFSET,
y: Y_OFFSET + HEIGHT * ARROW_DIRECTION - DISTANCE_BETWEEN_ARROWS / 2 * ARROW_DIRECTION + CURRENT_VALUE_DISTANCE * ARROW_DIRECTION
y: Y_OFFSET + HEIGHT * ARROW_DIRECTION - DISTANCE_BETWEEN_ARROWS / 2 * ARROW_DIRECTION + CURRENT_SCALE_DISTANCE * ARROW_DIRECTION
}
point6 = {
x: X_OFFSET + WIDTH / 2,
y: Y_OFFSET - DISTANCE_BETWEEN_ARROWS / 2 * ARROW_DIRECTION + CURRENT_VALUE_DISTANCE * ARROW_DIRECTION
y: Y_OFFSET - DISTANCE_BETWEEN_ARROWS / 2 * ARROW_DIRECTION + CURRENT_SCALE_DISTANCE * ARROW_DIRECTION
}
point4 = thisObject.container.frame.frameThisPoint(point4)
@@ -194,16 +535,4 @@ function newRateScale () {
browserCanvasContext.stroke()
}
}
function drawRate () {
if (thisObject.visible === false || thisObject.rate === undefined) { return }
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]
drawScaleDisplay(label1, label2, 10, 40, thisObject.container, thisObject.fitFunction)
}
}
+332
View File
@@ -0,0 +1,332 @@
function newTimeFrameScale () {
const MODULE_NAME = 'Time Frame Scale'
let thisObject = {
timeFrame: undefined,
container: undefined,
fitFunction: undefined,
payload: undefined,
isVisible: true,
layersOn: undefined,
onMouseOverSomeTimeMachineContainer: onMouseOverSomeTimeMachineContainer,
draw: draw,
drawForeground: drawForeground,
physics: physics,
getContainer: getContainer,
initialize: initialize,
finalize: finalize
}
const FILES_PERIOD_DEFAULT_VALUE = 0
const TIME_PERIOD_DEFAULT_VALUE = 0
const MIN_HEIGHT = 50
let visible = true
let isMouseOver
let filePeriodIndex = FILES_PERIOD_DEFAULT_VALUE
let timeFrameIndex = TIME_PERIOD_DEFAULT_VALUE
let timeFramesMasterArray = [marketFilesPeriods, dailyFilePeriods]
let timeFrameLabel = '24-hs'
let onMouseWheelEventSubscriptionId
let onViewportZoomChangedEventSubscriptionId
let onMouseOverEventSubscriptionId
let onMouseNotOverEventSubscriptionId
let limitingContainer
let mouse = {
position: {
x: 0,
y: 0
}
}
setupContainer()
return thisObject
function setupContainer () {
thisObject.container = newContainer()
thisObject.container.initialize(MODULE_NAME)
thisObject.container.isDraggeable = false
thisObject.container.isClickeable = false
thisObject.container.isWheelable = true
thisObject.container.detectMouseOver = true
thisObject.container.frame.width = UI_PANEL.WIDTH.NORMAL
thisObject.container.frame.height = 40
}
function finalize () {
thisObject.container.eventHandler.stopListening(onMouseWheelEventSubscriptionId)
canvas.chartSpace.viewport.eventHandler.stopListening(onViewportZoomChangedEventSubscriptionId)
thisObject.container.eventHandler.stopListening(onMouseOverEventSubscriptionId)
thisObject.container.eventHandler.stopListening(onMouseNotOverEventSubscriptionId)
thisObject.container.finalize()
thisObject.container = undefined
thisObject.fitFunction = undefined
thisObject.payload = undefined
limitingContainer = undefined
mouse = undefined
}
function initialize (pLimitingContainer) {
limitingContainer = pLimitingContainer
readObjectState()
newTimeFrame()
onMouseWheelEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseWheel', onMouseWheel)
onViewportZoomChangedEventSubscriptionId = canvas.chartSpace.viewport.eventHandler.listenToEvent('Zoom Changed', onViewportZoomChanged)
onMouseOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver)
onMouseNotOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver)
}
function onMouseOverSomeTimeMachineContainer (event) {
if (event.containerId === undefined) {
/* This happens when the mouse over was not at the instance of a certain scale, but anywhere else. */
visible = true
} else {
if (event.containerId === thisObject.container.id) {
visible = true
} else {
visible = false
turnOnCounter = 0
}
}
mouse = {
position: {
x: event.x,
y: event.y
}
}
}
function onMouseOver (event) {
isMouseOver = true
event.containerId = thisObject.container.id
thisObject.container.eventHandler.raiseEvent('onMouseOverScale', event)
}
function onMouseNotOver () {
isMouseOver = false
}
function physics () {
readObjectState()
positioningPhysics()
}
function positioningPhysics () {
/* Container Limits */
let upCorner = {
x: 0,
y: 0
}
let bottonCorner = {
x: limitingContainer.frame.width,
y: limitingContainer.frame.height
}
upCorner = transformThisPoint(upCorner, limitingContainer)
bottonCorner = transformThisPoint(bottonCorner, limitingContainer)
upCorner = limitingContainer.fitFunction(upCorner, true)
bottonCorner = limitingContainer.fitFunction(bottonCorner, true)
/* We will check if we need to change the bottom because of being one of many scales of the same type */
let displaceFactor = 0
if (thisObject.payload.parentNode === undefined) { return } // This happens when in the process of deleting the scale, timeline chart or time machine.
if (thisObject.payload.parentNode.type === 'Timeline Chart') {
if (thisObject.payload.parentNode.payload.parentNode !== undefined) {
if (thisObject.payload.parentNode.payload.parentNode.timeFrameScale !== undefined) {
if (thisObject.payload.parentNode.payload.parentNode.timeFrameScale.payload.isVisible === true) {
displaceFactor++
}
}
for (let i = 0; i < thisObject.payload.parentNode.payload.parentNode.timelineCharts.length; i++) {
let timelineChart = thisObject.payload.parentNode.payload.parentNode.timelineCharts[i]
if (timelineChart.timeFrameScale !== undefined) {
if (thisObject.payload.node.id !== timelineChart.timeFrameScale.id) {
if (timelineChart.timeFrameScale.payload.isVisible === true) {
displaceFactor++
}
} else {
break
}
}
}
}
}
bottonCorner.y = bottonCorner.y - thisObject.container.frame.height * displaceFactor
/* Positioning */
timePoint = {
x: 0,
y: limitingContainer.frame.height
}
timePoint = transformThisPoint(timePoint, limitingContainer.frame.container)
timePoint.x = mouse.position.x - thisObject.container.frame.width / 2
/* Checking against the container limits. */
if (timePoint.x < upCorner.x) { timePoint.x = upCorner.x }
if (timePoint.x + thisObject.container.frame.width > bottonCorner.x) { timePoint.x = bottonCorner.x - thisObject.container.frame.width }
if (timePoint.y < upCorner.y + thisObject.container.frame.height) { timePoint.y = upCorner.y + thisObject.container.frame.height }
if (timePoint.y > bottonCorner.y) { timePoint.y = bottonCorner.y }
thisObject.container.frame.position.x = timePoint.x
thisObject.container.frame.position.y = timePoint.y - thisObject.container.frame.height
thisObject.isVisible = true
thisObject.payload.isVisible = true
if (thisObject.container.frame.position.y + thisObject.container.frame.height > bottonCorner.y ||
thisObject.container.frame.position.y - thisObject.container.frame.height * 3 < upCorner.y) {
thisObject.isVisible = false
thisObject.payload.isVisible = false
}
if (thisObject.layersOn === 0) {
thisObject.isVisible = false
thisObject.payload.isVisible = false
}
}
function onViewportZoomChanged (event) {
if (event !== undefined) { // it is undefined when the level is just being animated.
if (event.shiftKey === false) { return } // with no shft key pressed, no automatic change in scale
let currentTimeFrame = thisObject.timeFrame
let timeFrame = recalculatePeriod(event.newLevel)
if (timeFrame !== currentTimeFrame) {
for (let i = 0; i < timeFramesMasterArray.length; i++) {
let timeFrameArray = timeFramesMasterArray[i]
for (let j = 0; j < timeFrameArray.length; j++) {
let record = timeFrameArray[j]
if (timeFrame === record[0]) {
filePeriodIndex = i
timeFrameIndex = j
}
}
}
newTimeFrame()
saveObjectState()
}
}
}
function onMouseWheel (event) {
delta = event.wheelDelta
if (delta < 0) {
timeFrameIndex--
if (timeFrameIndex < 0) {
filePeriodIndex--
if (filePeriodIndex < 0) {
filePeriodIndex = 0
timeFrameIndex = 0
} else {
timeFrameIndex = timeFramesMasterArray[filePeriodIndex].length - 1
}
}
} else {
timeFrameIndex++
if (timeFrameIndex > timeFramesMasterArray[filePeriodIndex].length - 1) {
filePeriodIndex++
if (filePeriodIndex > timeFramesMasterArray.length - 1) {
filePeriodIndex = timeFramesMasterArray.length - 1
timeFrameIndex = timeFramesMasterArray[filePeriodIndex].length - 1
} else {
timeFrameIndex = 0
}
}
}
newTimeFrame()
saveObjectState()
}
function getContainer (point) {
if (thisObject.container.frame.isThisPointHere(point, true) === true) {
return thisObject.container
}
}
function saveObjectState () {
try {
let code = JSON.parse(thisObject.payload.node.code)
code.value = timeFrameLabel
thisObject.payload.node.code = JSON.stringify(code)
} catch (err) {
// we ignore errors here since most likely they will be parsing errors.
}
}
function readObjectState () {
try {
let code = JSON.parse(thisObject.payload.node.code)
if (code.value !== timeFrameLabel) {
let found = false
for (let i = 0; i < timeFramesMasterArray.length; i++) {
let timeFrameArray = timeFramesMasterArray[i]
for (let j = 0; j < timeFrameArray.length; j++) {
let record = timeFrameArray[j]
if (code.value === record[1]) {
filePeriodIndex = i
timeFrameIndex = j
found = true
}
}
}
if (found === true) {
newTimeFrame()
} else {
saveObjectState()
}
}
} catch (err) {
// we ignore errors here since most likely they will be parsing errors.
}
}
function newTimeFrame () {
let timeFrameArray = timeFramesMasterArray[filePeriodIndex]
thisObject.timeFrame = timeFrameArray[timeFrameIndex][0]
timeFrameLabel = timeFrameArray[timeFrameIndex][1]
// console.log('NEW TIME FRAME LABEL', timeFrameLabel)
let event = {}
event.timeFrame = thisObject.timeFrame
thisObject.container.eventHandler.raiseEvent('Time Frame Value Changed', event)
}
function draw () {
drawScaleBox()
if (visible === false) {
drawScaleDisplayCover(thisObject.container)
}
}
function drawForeground () {
if (isMouseOver === true) {
drawScaleBox()
}
}
function drawScaleBox () {
if (timeFrameLabel === undefined) { return }
let label = timeFrameLabel.split('-')
let label1 = thisObject.payload.node.payload.parentNode.name
let label2 = label[0]
let label3 = label[1].toUpperCase()
let icon1 = canvas.designerSpace.iconByUiObjectType.get(thisObject.payload.node.payload.parentNode.type)
let icon2 = canvas.designerSpace.iconByUiObjectType.get(thisObject.payload.node.type)
let backgroundColor = UI_COLOR.BLACK
drawScaleDisplay(label1, label2, label3, 0, 0, 0, icon1, icon2, thisObject.container, backgroundColor)
}
}
-324
View File
@@ -1,324 +0,0 @@
function newTimePeriodScale () {
const MODULE_NAME = 'Time Period Scale'
let thisObject = {
timePeriod: undefined,
container: undefined,
draw: draw,
getContainer: getContainer,
initialize: initialize,
finalize: finalize
}
const FILES_PERIOD_DEFAULT_VALUE = 0
const TIME_PERIOD_DEFAULT_VALUE = 0
const MIN_HEIGHT = 50
let mouse = {
position: {
x: 0,
y: 0
}
}
let visible = true
let timeLineCoordinateSystem
let objectStorage = {}
let filePeriodIndex = FILES_PERIOD_DEFAULT_VALUE
let timePeriodIndex = TIME_PERIOD_DEFAULT_VALUE
let timePeriodsMasterArray = [marketFilesPeriods, dailyFilePeriods]
let timePeriodLabel = ''
let onMouseWheelEventSubscriptionId
let onMouseOverEventSubscriptionId
let onMouseNotOverEventSubscriptionId
let onZoomChangedEventSubscriptionId
setupContainer()
return thisObject
function setupContainer () {
thisObject.container = newContainer()
thisObject.container.initialize(MODULE_NAME)
thisObject.container.isDraggeable = false
thisObject.container.isClickeable = false
thisObject.container.isWheelable = true
}
function finalize () {
thisObject.container.eventHandler.stopListening(onMouseWheelEventSubscriptionId)
thisObject.container.eventHandler.stopListening(onMouseOverEventSubscriptionId)
thisObject.container.eventHandler.stopListening(onMouseNotOverEventSubscriptionId)
thisObject.container.eventHandler.stopListening(onZoomChangedEventSubscriptionId)
timeLineCoordinateSystem = undefined
objectStorage = undefined
thisObject.container.finalize()
thisObject.container = undefined
setupContainer()
}
function initialize (pTimeLineCoordinateSystem) {
timeLineCoordinateSystem = pTimeLineCoordinateSystem
onMouseWheelEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseWheel', onMouseWheel)
readObjectState()
newTimePeriod()
onMouseOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseOver', function (event) {
mouse.position.x = event.x
mouse.position.y = event.y
visible = true
})
onMouseWheelEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseNotOver', function (event) {
visible = false
})
onZoomChangedEventSubscriptionId = viewPort.eventHandler.listenToEvent('Zoom Changed', onZoomChanged)
}
function onZoomChanged (event) {
if (event !== undefined) { // it is undefined when the level is just being animated.
let currentTimePeriod = thisObject.timePeriod
let timePeriod = recalculatePeriod(event.newLevel)
if (timePeriod !== currentTimePeriod) {
for (let i = 0; i < timePeriodsMasterArray.length; i++) {
let timePeriodArray = timePeriodsMasterArray[i]
for (let j = 0; j < timePeriodArray.length; j++) {
let record = timePeriodArray[j]
if (timePeriod === record[0]) {
filePeriodIndex = i
timePeriodIndex = j
}
}
}
saveObjectState()
newTimePeriod()
}
}
}
function onMouseWheel (event) {
delta = event.wheelDelta
if (delta < 0) {
timePeriodIndex--
if (timePeriodIndex < 0) {
filePeriodIndex--
if (filePeriodIndex < 0) {
filePeriodIndex = 0
timePeriodIndex = 0
} else {
timePeriodIndex = timePeriodsMasterArray[filePeriodIndex].length - 1
}
}
} else {
timePeriodIndex++
if (timePeriodIndex > timePeriodsMasterArray[filePeriodIndex].length - 1) {
filePeriodIndex++
if (filePeriodIndex > timePeriodsMasterArray.length - 1) {
filePeriodIndex = timePeriodsMasterArray.length - 1
timePeriodIndex = timePeriodsMasterArray[filePeriodIndex].length - 1
} else {
timePeriodIndex = 0
}
}
}
saveObjectState()
newTimePeriod()
}
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
if (thisObject.container.frame.isThisPointHere(point, undefined, true) === true) {
return thisObject.container
} else {
/* This point does not belong to this space. */
return undefined
}
}
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 }
/* 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. */
let frame = thisObject.container.parentContainer.frame
let point1
let point2
let point3
let point4
point1 = {
x: 0,
y: frame.height - frame.height * 2 / 100
}
point2 = {
x: frame.width,
y: frame.height - frame.height * 2 / 100
}
point3 = {
x: frame.width,
y: frame.height
}
point4 = {
x: 0,
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 (point3.y - point2.y < MIN_HEIGHT) {
point1.y = point3.y - MIN_HEIGHT
point2.y = point3.y - MIN_HEIGHT
}
/* Lets start the drawing. */
let displacement = viewPort.margins.BOTTOM - COCKPIT_SPACE_HEIGHT
/*
browserCanvasContext.beginPath()
browserCanvasContext.moveTo(point1.x, point1.y + displacement)
browserCanvasContext.lineTo(point2.x, point2.y + displacement)
browserCanvasContext.lineTo(point3.x, point3.y + displacement)
browserCanvasContext.lineTo(point4.x, point4.y + displacement)
browserCanvasContext.lineTo(point1.x, point1.y + displacement)
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 + displacement
thisObject.container.frame.width = point2.x - point1.x
thisObject.container.frame.height = point3.y - point2.y
/* 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 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 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: 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)
}
}
+255 -52
View File
@@ -2,21 +2,28 @@ function newTimeScale () {
const MODULE_NAME = 'Time Scale'
let thisObject = {
lenghtPercentage: undefined,
scale: undefined,
container: undefined,
date: undefined,
fitFunction: undefined,
visible: true,
payload: undefined,
isVisible: true,
fromDate: undefined,
toDate: undefined,
onMouseOverSomeTimeMachineContainer: onMouseOverSomeTimeMachineContainer,
physics: physics,
draw: draw,
drawForeground: drawForeground,
getContainer: getContainer,
initialize: initialize,
finalize: finalize
}
const LENGHT_PERCENTAGE_DEFAULT_VALUE = 5
const STEP_SIZE = 5
const MIN_HEIGHT = 50
const DEFAULT_SCALE = 0
const STEP_SCALE = 2.5
const MIN_SCALE = 0
const MAX_SCALE = 250
const SNAP_THRESHOLD_SCALE = 0
thisObject.container = newContainer()
thisObject.container.initialize(MODULE_NAME)
@@ -26,57 +33,120 @@ function newTimeScale () {
thisObject.container.isWheelable = true
thisObject.container.detectMouseOver = true
thisObject.container.frame.width = 190
thisObject.container.frame.height = 25
thisObject.container.frame.width = UI_PANEL.WIDTH.NORMAL
thisObject.container.frame.height = 40
let visible = true
let isMouseOver
let onMouseWheelEventSubscriptionId
let onMouseOverEventSubscriptionId
let onMouseNotOverEventSubscriptionId
let coordinateSystem
let limitingContainer
let mouse = {
position: {
x: 0,
y: 0
}
}
let scaleTimer = 0
return thisObject
function finalize () {
thisObject.container.eventHandler.stopListening(onMouseWheelEventSubscriptionId)
thisObject.container.eventHandler.stopListening(onMouseOverEventSubscriptionId)
thisObject.container.eventHandler.stopListening(onMouseNotOverEventSubscriptionId)
thisObject.container.finalize()
thisObject.container = undefined
thisObject.fitFunction = undefined
thisObject.payload = undefined
coordinateSystem = undefined
limitingContainer = undefined
mouse = undefined
}
function initialize () {
thisObject.container.eventHandler.listenToEvent('onMouseWheel', onMouseWheel)
thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver)
thisObject.container.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver)
function initialize (pCoordinateSystem, pLimitingContainer) {
coordinateSystem = pCoordinateSystem
limitingContainer = pLimitingContainer
thisObject.lenghtPercentage = window.localStorage.getItem(MODULE_NAME)
if (!thisObject.lenghtPercentage) {
thisObject.lenghtPercentage = LENGHT_PERCENTAGE_DEFAULT_VALUE
} else {
thisObject.lenghtPercentage = JSON.parse(thisObject.lenghtPercentage)
}
thisObject.fromDate = coordinateSystem.min.x
thisObject.toDate = coordinateSystem.max.x
onMouseWheelEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseWheel', onMouseWheel)
onMouseOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver)
onMouseNotOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver)
thisObject.scale = DEFAULT_SCALE
readObjectState()
let event = {}
event.lenghtPercentage = thisObject.lenghtPercentage
thisObject.container.eventHandler.raiseEvent('Lenght Percentage Changed', event)
event.scale = thisObject.scale
thisObject.container.eventHandler.raiseEvent('Time Scale Value Changed', event)
}
function onMouseOver () {
function onMouseOverSomeTimeMachineContainer (event) {
if (event.containerId === undefined) {
/* This happens when the mouse over was not at the instance of a certain scale, but anywhere else. */
visible = true
} else {
if (event.containerId === thisObject.container.id) {
visible = true
} else {
visible = false
turnOnCounter = 0
}
}
mouse = {
position: {
x: event.x,
y: event.y
}
}
}
function onMouseOver (event) {
isMouseOver = true
event.containerId = thisObject.container.id
thisObject.container.eventHandler.raiseEvent('onMouseOverScale', event)
}
function onMouseNotOver () {
isMouseOver = false
scaleTimer = 0
}
function onMouseWheel (event) {
let morePower = 1
if (event.buttons === 4) { morePower = 5 } // Mouse wheel pressed.
delta = event.wheelDelta
if (delta < 0) {
thisObject.lenghtPercentage = thisObject.lenghtPercentage - STEP_SIZE
if (thisObject.lenghtPercentage < STEP_SIZE) { thisObject.lenghtPercentage = STEP_SIZE }
thisObject.scale = thisObject.scale - STEP_SCALE * morePower
if (thisObject.scale < MIN_SCALE) { thisObject.scale = MIN_SCALE }
} else {
thisObject.lenghtPercentage = thisObject.lenghtPercentage + STEP_SIZE
if (thisObject.lenghtPercentage > 400) { thisObject.lenghtPercentage = 400 }
thisObject.scale = thisObject.scale + STEP_SCALE * morePower
if (thisObject.scale > MAX_SCALE) { thisObject.scale = MAX_SCALE }
}
event.lenghtPercentage = thisObject.lenghtPercentage
thisObject.container.eventHandler.raiseEvent('Lenght Percentage Changed', event)
if (
thisObject.scale <= DEFAULT_SCALE + SNAP_THRESHOLD_SCALE &&
thisObject.scale >= DEFAULT_SCALE - SNAP_THRESHOLD_SCALE
) {
event.scale = DEFAULT_SCALE
} else {
event.scale = thisObject.scale
}
window.localStorage.setItem(MODULE_NAME, thisObject.lenghtPercentage)
event.isUserAction = true
thisObject.container.eventHandler.raiseEvent('Time Scale Value Changed', event)
saveObjectState()
scaleTimer = 100
}
function getContainer (point) {
@@ -85,18 +155,163 @@ function newTimeScale () {
}
}
function physics () {
function saveObjectState () {
try {
let code = JSON.parse(thisObject.payload.node.code)
code.scale = thisObject.scale / MAX_SCALE * 100
code.scale = code.scale.toFixed(0)
code.fromDate = (new Date(thisObject.fromDate)).toISOString()
code.toDate = (new Date(thisObject.toDate)).toISOString()
thisObject.payload.node.code = JSON.stringify(code, null, 4)
} catch (err) {
// we ignore errors here since most likely they will be parsing errors.
}
}
function readObjectState () {
try {
let code = JSON.parse(thisObject.payload.node.code)
if (isNaN(code.scale) || code.scale === null || code.scale === undefined) {
// not using this value
} else {
code.scale = code.scale / 100 * MAX_SCALE
if (code.scale < MIN_SCALE) { code.scale = MIN_SCALE }
if (code.scale > MAX_SCALE) { code.scale = MAX_SCALE }
if (code.scale !== thisObject.scale) {
thisObject.scale = code.scale
let event = {}
if (
thisObject.scale <= DEFAULT_SCALE + SNAP_THRESHOLD_SCALE &&
thisObject.scale >= DEFAULT_SCALE - SNAP_THRESHOLD_SCALE
) {
event.scale = DEFAULT_SCALE
} else {
event.scale = thisObject.scale
}
thisObject.container.eventHandler.raiseEvent('Time Scale Value Changed', event)
}
}
if (
(isNaN(Date.parse(code.fromDate)) || code.fromDate === null || code.fromDate === undefined) ||
(isNaN(Date.parse(code.toDate)) || code.toDate === null || code.toDate === undefined)
) {
// not using this value
} else {
if (thisObject.fromDate !== Date.parse(code.fromDate) || thisObject.toDate !== Date.parse(code.toDate)) {
thisObject.fromDate = Date.parse(code.fromDate)
thisObject.toDate = Date.parse(code.toDate)
coordinateSystem.min.x = thisObject.fromDate
coordinateSystem.max.x = thisObject.toDate
coordinateSystem.recalculateScale()
}
}
saveObjectState() // this overrides any invalid value at the config.
} catch (err) {
// we ignore errors here since most likely they will be parsing errors.
}
}
function physics () {
scaleTimer--
readObjectState()
positioningPhysics()
}
function positioningPhysics () {
/* Container Limits */
let upCorner = {
x: 0,
y: 0
}
let bottonCorner = {
x: limitingContainer.frame.width,
y: limitingContainer.frame.height
}
upCorner = transformThisPoint(upCorner, limitingContainer)
bottonCorner = transformThisPoint(bottonCorner, limitingContainer)
upCorner = limitingContainer.fitFunction(upCorner, true)
bottonCorner = limitingContainer.fitFunction(bottonCorner, true)
/* Mouse Position Date Calculation */
let timePoint = {
x: mouse.position.x,
y: 0
}
let mouseDate = getDateFromPoint(timePoint, limitingContainer, coordinateSystem)
thisObject.date = new Date(mouseDate)
/* timeScale Positioning */
timePoint = {
x: 0,
y: 0
}
timePoint = transformThisPoint(timePoint, limitingContainer.frame.container)
timePoint.x = mouse.position.x - thisObject.container.frame.width / 2
/* Checking against the container limits. */
if (timePoint.x < upCorner.x) { timePoint.x = upCorner.x }
if (timePoint.x + thisObject.container.frame.width > bottonCorner.x) { timePoint.x = bottonCorner.x - thisObject.container.frame.width }
if (timePoint.y < upCorner.y) { timePoint.y = upCorner.y }
if (timePoint.y + thisObject.container.frame.height > bottonCorner.y) { timePoint.y = bottonCorner.y - thisObject.container.frame.height }
thisObject.container.frame.position.x = timePoint.x
thisObject.container.frame.position.y = timePoint.y
thisObject.isVisible = true
if (thisObject.container.frame.position.y + thisObject.container.frame.height * 4 > bottonCorner.y ||
thisObject.container.frame.position.y < upCorner.y) {
thisObject.isVisible = false
}
}
function draw () {
drawTime()
drawArrows()
drawScaleBox()
if (visible === false) {
drawScaleDisplayCover(thisObject.container)
}
}
function drawForeground () {
if (isMouseOver === true) {
drawScaleBox()
drawArrows()
}
}
function drawScaleBox () {
if (thisObject.date === undefined) { return }
let label = thisObject.date.toUTCString()
let labelArray = label.split(' ')
let label1 = thisObject.payload.node.payload.parentNode.name
let label2 = labelArray[1] + ' ' + labelArray[2] + ' ' + labelArray[3]
let label3 = labelArray[4]
let icon1 = canvas.designerSpace.iconByUiObjectType.get(thisObject.payload.node.payload.parentNode.type)
let icon2 = canvas.designerSpace.iconByUiObjectType.get(thisObject.payload.node.type)
let backgroundColor = UI_COLOR.BLACK
if (scaleTimer > 0) {
label2 = (thisObject.scale / MAX_SCALE * 100).toFixed(0)
label3 = 'SCALE'
}
drawScaleDisplay(label1, label2, label3, 0, 0, 0, icon1, icon2, thisObject.container, backgroundColor)
}
function drawArrows () {
if (isMouseOver !== true) { return }
if (thisObject.visible === false || thisObject.date === undefined) { return }
if (visible === false || thisObject.date === undefined) { return }
const X_OFFSET = thisObject.container.frame.width / 2
const Y_OFFSET = thisObject.container.frame.height / 2 - 10
@@ -106,8 +321,8 @@ function newTimeScale () {
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 + 400 + DISTANCE_BETWEEN_ARROWS
const CURRENT_SCALE_DISTANCE = MIN_DISTANCE_FROM_CENTER + thisObject.scale
const MAX_DISTANCE_FROM_CENTER = MIN_DISTANCE_FROM_CENTER + MAX_SCALE + DISTANCE_BETWEEN_ARROWS
let ARROW_DIRECTION = 0
@@ -118,17 +333,17 @@ function newTimeScale () {
function drawTwoArrows () {
point1 = {
x: X_OFFSET - WIDTH / 2 * ARROW_DIRECTION + DISTANCE_BETWEEN_ARROWS / 2 * ARROW_DIRECTION + CURRENT_VALUE_DISTANCE * ARROW_DIRECTION,
x: X_OFFSET - WIDTH / 2 * ARROW_DIRECTION + DISTANCE_BETWEEN_ARROWS / 2 * ARROW_DIRECTION + CURRENT_SCALE_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,
x: X_OFFSET + WIDTH / 2 * ARROW_DIRECTION + DISTANCE_BETWEEN_ARROWS / 2 * ARROW_DIRECTION + CURRENT_SCALE_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,
x: X_OFFSET - WIDTH / 2 * ARROW_DIRECTION + DISTANCE_BETWEEN_ARROWS / 2 * ARROW_DIRECTION + CURRENT_SCALE_DISTANCE * ARROW_DIRECTION,
y: Y_OFFSET + HEIGHT
}
@@ -137,17 +352,17 @@ function newTimeScale () {
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,
x: X_OFFSET - WIDTH / 2 * ARROW_DIRECTION - DISTANCE_BETWEEN_ARROWS / 2 * ARROW_DIRECTION + CURRENT_SCALE_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,
x: X_OFFSET + WIDTH / 2 * ARROW_DIRECTION - DISTANCE_BETWEEN_ARROWS / 2 * ARROW_DIRECTION + CURRENT_SCALE_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,
x: X_OFFSET - WIDTH / 2 * ARROW_DIRECTION - DISTANCE_BETWEEN_ARROWS / 2 * ARROW_DIRECTION + CURRENT_SCALE_DISTANCE * ARROW_DIRECTION,
y: Y_OFFSET + HEIGHT
}
@@ -195,16 +410,4 @@ function newTimeScale () {
browserCanvasContext.stroke()
}
}
function drawTime () {
if (thisObject.visible === false || thisObject.date === undefined) { return }
let label = thisObject.date.toUTCString()
let labelArray = label.split(' ')
let label1 = labelArray[1] + ' ' + labelArray[2] + ' ' + labelArray[3]
let label2 = labelArray[4]
drawScaleDisplay(label1, label2, 10, 60, thisObject.container, thisObject.fitFunction)
}
}
+187 -61
View File
@@ -13,17 +13,20 @@ function newChartSpace () {
logger.fileName = MODULE_NAME
let thisObject = {
visible: true,
visible: undefined,
container: undefined,
timeMachines: [],
inViewport: undefined,
timeMachines: undefined,
viewport: undefined,
payload: undefined,
reset: reset,
oneScreenUp: oneScreenUp,
oneScreenDown: oneScreenDown,
oneScreenLeft: oneScreenLeft,
oneScreenRight: oneScreenRight,
fitIntoVisibleArea: fitIntoVisibleArea,
fitFunction: fitFunction,
isThisPointVisible: isThisPointVisible,
physics: physics,
drawBackground: drawBackground,
draw: draw,
getContainer: getContainer, // returns the inner most container that holds the point received by parameter.
initialize: initialize,
@@ -31,13 +34,27 @@ function newChartSpace () {
}
let canvasBrowserResizedEventSubscriptionId
let timeMachinesMap
let syncWithDesignerLoop
const PERCENTAGE_OF_SCREEN_FOR_DISPLACEMENT = 25
setupContainer()
initialSetup()
return thisObject
function setupContainer () {
function reset () {
finalize()
initialSetup()
initialize()
}
function initialSetup () {
thisObject.timeMachines = []
thisObject.visible = true
timeMachinesMap = new Map()
syncWithDesignerLoop = 0
thisObject.inViewport = new Map()
thisObject.container = newContainer()
thisObject.container.initialize(MODULE_NAME)
@@ -51,45 +68,46 @@ function newChartSpace () {
timeMachine.finalize()
}
thisObject.inViewport = undefined
thisObject.timeMachines = undefined
timeMachinesMap = undefined
thisObject.container.eventHandler.stopListening(canvasBrowserResizedEventSubscriptionId)
thisObject.container.finalize()
thisObject.container = undefined
setupContainer()
thisObject.viewport.finalize()
thisObject.viewport = undefined
thisObject.payload = undefined
}
function initialize () {
let initializedCounter = 0
let toInitialize = 1
canvasBrowserResizedEventSubscriptionId = window.canvasApp.eventHandler.listenToEvent('Browser Resized', resize)
/* We create the first of many possible time machines that could live at the Chart Space. */
let timeMachine = newTimeMachine()
/* 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.fitFunction = fitIntoVisibleArea
timeMachine.initialize(onTimeMachineInitialized)
function onTimeMachineInitialized (err) {
initializedCounter++
if (err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) {
if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> Initialization Failed. -> Err ' + err.message) }
return
}
thisObject.timeMachines.push(timeMachine)
if (initializedCounter === toInitialize) {
viewPort.raiseEvents() // These events will impacts on objects just initialized.
let rootNodes = canvas.designerSpace.workspace.workspaceNode.rootNodes
for (let i = 0; i < rootNodes.length; i++) {
let rootNode = rootNodes[i]
if (rootNode.type === 'Charting Space') {
thisObject.payload = rootNode.payload
}
}
if (thisObject.payload === undefined) {
if (ERROR_LOG === true) { logger.write('[WARN] initialize -> There must exist a Charting Space at the Designer Space in order to enable Charts. PLease create one and refreash your browser. ') }
return
}
thisObject.viewport = newViewport()
if (thisObject.payload.node.viewport === undefined) {
if (ERROR_LOG === true) { logger.write('[WARN] initialize -> There must exist a Viewport node attached to the Charting Space node in order for the Viewport save its properties. ') }
return
} else {
thisObject.viewport.payload = thisObject.payload.node.viewport.payload
}
thisObject.viewport.initialize()
canvasBrowserResizedEventSubscriptionId = canvas.eventHandler.listenToEvent('Browser Resized', resize)
}
function getContainer (point, purpose) {
@@ -97,12 +115,25 @@ function newChartSpace () {
let container
/* Now we see which is the inner most container that has it */
/* This first step is not actually to get the container but to allow things to be turned off in case there is a switch of focus from one time machine to another */
for (let i = 0; i < thisObject.timeMachines.length; i++) {
container = thisObject.timeMachines[i].container
if (purpose === GET_CONTAINER_PURPOSE.MOUSE_OVER) {
container.eventHandler.raiseEvent('onMouseNotOver')
}
}
/* 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 (purpose !== undefined) {
if (container.isForThisPurpose(purpose)) {
if (thisObject.container.frame.isThisPointHere(point, true) === true) {
return container
}
}
} else {
if (thisObject.container.frame.isThisPointHere(point, true) === true) {
return container
}
@@ -118,6 +149,7 @@ function newChartSpace () {
}
function resize () {
thisObject.viewport.resize()
thisObject.container.frame.width = browserCanvas.width
thisObject.container.frame.height = COCKPIT_SPACE_POSITION
}
@@ -125,10 +157,10 @@ function newChartSpace () {
function oneScreenUp () {
let displaceVector = {
x: 0,
y: +browserCanvas.height * PERCENTAGE_OF_SCREEN_FOR_DISPLACEMENT / 100
y: browserCanvas.height * PERCENTAGE_OF_SCREEN_FOR_DISPLACEMENT / 100
}
viewPort.displace(displaceVector)
canvas.chartSpace.viewport.displace(displaceVector)
}
function oneScreenDown () {
@@ -137,7 +169,7 @@ function newChartSpace () {
y: -browserCanvas.height * PERCENTAGE_OF_SCREEN_FOR_DISPLACEMENT / 100
}
viewPort.displace(displaceVector)
canvas.chartSpace.viewport.displace(displaceVector)
}
function oneScreenLeft () {
@@ -146,7 +178,7 @@ function newChartSpace () {
y: 0
}
viewPort.displace(displaceVector, true)
canvas.chartSpace.viewport.displace(displaceVector, true)
}
function oneScreenRight () {
@@ -155,10 +187,10 @@ function newChartSpace () {
y: 0
}
viewPort.displace(displaceVector, true)
canvas.chartSpace.viewport.displace(displaceVector, true)
}
function fitIntoVisibleArea (point) {
function fitFunction (point, fullVisible) {
/* Here we check the boundaries of the resulting points, so they dont go out of the visible area. */
let returnPoint = {
@@ -174,12 +206,18 @@ function newChartSpace () {
returnPoint.x = 0
}
if (point.y > COCKPIT_SPACE_POSITION + COCKPIT_SPACE_HEIGHT / 2) {
returnPoint.y = COCKPIT_SPACE_POSITION + COCKPIT_SPACE_HEIGHT / 2
if (fullVisible === true) {
if (point.y > COCKPIT_SPACE_POSITION) {
returnPoint.y = COCKPIT_SPACE_POSITION
}
} else {
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
if (point.y < TOP_SPACE_HEIGHT) {
returnPoint.y = TOP_SPACE_HEIGHT
}
return returnPoint
@@ -206,8 +244,77 @@ function newChartSpace () {
}
function physics () {
if (thisObject.viewport !== undefined) {
thisObject.viewport.physics()
}
thisObjectPhysics()
childrenPhysics()
syncWithDesigner()
}
function syncWithDesigner () {
if (thisObject.payload === undefined) { return }
if (thisObject.payload.node === undefined) { return }
syncWithDesignerLoop = syncWithDesignerLoop + 0.00000000001
if (thisObject.payload.node.timeMachines !== undefined) {
for (let j = 0; j < thisObject.payload.node.timeMachines.length; j++) {
let node = thisObject.payload.node.timeMachines[j]
let timeMachine = timeMachinesMap.get(node.id)
if (timeMachine === undefined) {
/* The time machine node is new, thus we need to initialize a new timeMachine */
initializeTimeMachine(node, syncWithDesignerLoop)
} else {
/* The time machine already exists, we tag it as existing at the current loop. */
timeMachine.syncWithDesignerLoop = syncWithDesignerLoop
}
}
}
/* We check all the timeMachines we have to see if we need to remove any of them */
for (let i = 0; i < thisObject.timeMachines.length; i++) {
let timeMachine = thisObject.timeMachines[i]
if (timeMachine.syncWithDesignerLoop < syncWithDesignerLoop) {
/* Must be removed */
timeMachine.finalize()
timeMachinesMap.delete(timeMachine.nodeId)
thisObject.timeMachines.splice(i, 1)
/* We remove one at the time */
return
}
}
function initializeTimeMachine (node, syncWithDesignerLoop) {
if (node.payload === undefined) { return } // not ready to consider this Time Machine
if (node.payload.uiObject === undefined) { return }
let timeMachine = newTimeMachine()
timeMachine.syncWithDesignerLoop = syncWithDesignerLoop
timeMachine.payload = node.payload
timeMachine.nodeId = node.id
timeMachinesMap.set(node.id, timeMachine)
timeMachine.payload.uiObject.setValue('Loading...')
/* Setting up the new time machine. */
timeMachine.container.frame.position.x = browserCanvas.width / 2 - TIME_MACHINE_WIDTH / 2
timeMachine.container.frame.position.y = browserCanvas.height / 2 - TIME_MACHINE_HEIGHT / 2
timeMachine.initialize(onTimeMachineInitialized)
function onTimeMachineInitialized (err) {
if (err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) {
if (ERROR_LOG === true) { logger.write('[ERROR] syncWithDesigner -> initializeTimeMachine -> Initialization Failed. -> Err ' + err.message) }
return
}
thisObject.timeMachines.push(timeMachine)
timeMachine.payload.uiObject.setValue('')
if (canvas.chartSpace.viewport !== undefined) {
canvas.chartSpace.viewport.raiseEvents() // These events will impacts on objects just initialized.
}
}
}
}
function thisObjectPhysics () {
@@ -219,27 +326,55 @@ function newChartSpace () {
thisObject.visible = true
}
viewPort.resize()
if (canvas.chartSpace.viewport !== undefined) {
canvas.chartSpace.viewport.resize()
}
}
function childrenPhysics () {
for (let i = 0; i < thisObject.timeMachines.length; i++) {
let timeMachine = thisObject.timeMachines[i]
if (timeMachine.payload.node === undefined) {
continue
}
if (timeMachine.container.frame.isInViewPort()) {
thisObject.inViewport.set(timeMachine.payload.node.id, timeMachine)
} else {
thisObject.inViewport.delete(timeMachine.payload.node.id)
}
timeMachine.physics()
}
}
function drawBackground () {
if (thisObject.visible !== true) { return }
drawSpaceBackground()
for (let i = 0; i < thisObject.timeMachines.length; i++) {
let timeMachine = thisObject.timeMachines[i]
let timeMachine = thisObject.timeMachines[thisObject.timeMachines.length - i - 1]
timeMachine.drawBackground()
}
}
function draw () {
if (thisObject.visible !== true) { return }
drawBackground()
for (let i = 0; i < thisObject.timeMachines.length; i++) {
let timeMachine = thisObject.timeMachines[thisObject.timeMachines.length - i - 1]
timeMachine.draw()
}
drawForeground()
}
function drawForeground () {
for (let i = 0; i < thisObject.timeMachines.length; i++) {
let timeMachine = thisObject.timeMachines[thisObject.timeMachines.length - i - 1]
timeMachine.drawForeground()
}
}
function drawSpaceBackground () {
let opacity = '1'
let fromPoint = {
@@ -258,13 +393,4 @@ function newChartSpace () {
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()
}
}
}
+9 -7
View File
@@ -62,10 +62,10 @@
thisObject.container.frame.position.y = browserCanvas.height * INITIAL_POSITION / 100 - COCKPIT_SPACE_HEIGHT
}
canvasBrowserResizedEventSubscriptionId = window.canvasApp.eventHandler.listenToEvent('Browser Resized', resize)
canvasBrowserResizedEventSubscriptionId = canvas.eventHandler.listenToEvent('Browser Resized', resize)
selfMouseClickEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick)
thisObject.assetBalances = newAssetBalances()
thisObject.assetBalances = newQuotedAssetalances()
thisObject.assetBalances.initialize()
thisObject.fullscreen = newFullScreen()
@@ -150,14 +150,16 @@
spacePosition: COCKPIT_SPACE_POSITION
}
window.localStorage.setItem(MODULE_NAME, JSON.stringify(storage))
viewPort.resize()
if (canvas.chartSpace.viewport !== undefined) {
canvas.chartSpace.viewport.resize()
}
}
function getContainer (point) {
let container
container = thisObject.fullscreen.getContainer(point)
if (container !== undefined) { return container }
// container = thisObject.fullscreen.getContainer(point)
// if (container !== undefined) { return container }
if (thisObject.container.frame.isThisPointHere(point, true) === true) {
return thisObject.container
@@ -172,7 +174,7 @@
drawBackground()
thisObject.assetBalances.draw()
thisObject.fullscreen.draw()
// thisObject.fullscreen.draw()
}
function drawBackground () {
@@ -183,7 +185,7 @@
y: 0
}
const RED_LINE_HIGHT = 5
const RED_LINE_HIGHT = 2
zeroPoint = thisObject.container.frame.frameThisPoint(zeroPoint)
+78 -11
View File
@@ -35,14 +35,6 @@ function newDesignerSpace () {
}
function buildIconByUiObjectTypeMap () {
const relationshipArray = []
for (let i = 0; i < relationshipArray.length; i++) {
let record = relationshipArray[i]
let icon = thisObject.iconCollection.get(record[1])
thisObject.iconByUiObjectType.set(record[0], icon)
}
/* Take types-icons relationships defined at the schema */
for (let i = 0; i < APP_SCHEMA_ARRAY.length; i++) {
let nodeDefinition = APP_SCHEMA_ARRAY[i]
@@ -139,7 +131,7 @@ function newDesignerSpace () {
'bot-indicator',
'bot-sensor',
'time-period',
'team',
'data-mine',
'procedure-loop',
'calculations-procedure',
'data-building-procedure',
@@ -173,7 +165,83 @@ function newDesignerSpace () {
'shapes-polygon',
'data-entry',
'data-formula',
'clone'
'clone',
'exchange-account-asset',
'exchange-account-key',
'user-keys',
'user-assets',
'asset',
'exchange-accounts',
'user-account',
'market',
'exchange-assets',
'crypto-exchanges',
'crypto-exchange',
'exchange-markets',
'charting-space',
'time-line-chart',
'time-frame-scale',
'time-scale',
'rate-scale',
'time-machine',
'data-product',
'single-market-data',
'data-storage',
'dataset',
'viewport',
'bitfinex',
'binance',
'kucoin',
'bittrex',
'kraken',
'poloniex',
'upbit',
'monero',
'tether',
'tron',
'stellar',
'qtum',
'neo',
'litecoin',
'ethereum-classic',
'ethereum',
'eos',
'dash',
'cardano',
'bitcoin-cash',
'bitcoin',
'binance-coin',
'trend',
'oscillator',
'moving-average',
'histogram',
'band',
'volume',
'candles',
'bitmex',
'liquid',
'hitbtc',
'us-dollar',
'distance-to-parent-200',
'distance-to-parent-150',
'distance-to-parent-100',
'distance-to-parent-050',
'distance-to-parent-025',
'distance-to-parent-000',
'angle-to-parent-360',
'angle-to-parent-180',
'angle-to-parent-090',
'angle-to-parent-045',
'angle-to-parent-000',
'data-mining',
'initial-definition',
'next-phase-event',
'testing-environment',
'production-environment',
'task-manager',
'session-based-data',
'session-independent-data',
'session-reference'
]
for (let i = 0; i < iconsNames.length; i++) {
@@ -196,7 +264,6 @@ function newDesignerSpace () {
}
function physics () {
if (visible !== true) { return }
thisObject.workspace.physics()
}
+5 -32
View File
@@ -9,9 +9,7 @@ function newFloatingSpace () {
let thisObject = {
floatingLayer: undefined, // This is the array of floatingObjects being displayed
profileBalls: undefined,
uiObjectConstructor: undefined,
noteSets: undefined,
container: undefined,
oneScreenUp: oneScreenUp,
oneScreenDown: oneScreenDown,
@@ -21,7 +19,6 @@ function newFloatingSpace () {
fitIntoVisibleArea: fitIntoVisibleArea,
isThisPointVisible: isThisPointVisible,
isItFar: isItFar,
warmUp: warmUp,
makeVisible: makeVisible,
makeInvisible: makeInvisible,
draw: draw,
@@ -41,7 +38,6 @@ function newFloatingSpace () {
let devicePixelRatio = window.devicePixelRatio
const SPACE_SIZE = 50000
const WARM_UP_LIMIT = 10000
thisObject.container.frame.width = SPACE_SIZE
thisObject.container.frame.height = SPACE_SIZE
@@ -49,7 +45,6 @@ function newFloatingSpace () {
thisObject.container.frame.position.y = browserCanvas.height / 2 - thisObject.container.frame.height / 2
let visible = false
let warmingUpCounter = 0
const PERCENTAGE_OF_SCREEN_FOR_DISPLACEMENT = 25
let eventSubscriptionId
@@ -60,15 +55,11 @@ function newFloatingSpace () {
thisObject.container.eventHandler.stopListening(eventSubscriptionId)
thisObject.floatingLayer.finalize()
thisObject.profileBalls.finalize()
thisObject.uiObjectConstructor.finalize()
thisObject.noteSets.finalize()
thisObject.container.finalize()
thisObject.floatingLayer = undefined
thisObject.profileBalls = undefined
thisObject.uiObjectConstructor = undefined
thisObject.noteSets = undefined
thisObject.container = undefined
}
@@ -76,36 +67,16 @@ function newFloatingSpace () {
thisObject.floatingLayer = newFloatingLayer()
thisObject.floatingLayer.initialize()
thisObject.profileBalls = newProfileBalls()
thisObject.profileBalls.initialize(thisObject.floatingLayer)
thisObject.noteSets = newNoteSets()
thisObject.noteSets.initialize(thisObject.floatingLayer)
thisObject.uiObjectConstructor = newUiObjectConstructor()
thisObject.uiObjectConstructor.initialize(thisObject.floatingLayer)
eventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseWheel', onMouseWheel)
}
function warmUp () {
warmingUpCounter = 0
}
function isItFar (payload, dontCheckParent) {
/* If for any reason the paylaod is undefined we return false */
if (payload === undefined) { return false }
/*
We need a warm up in order to allow all objects to stabilize into a consistant state.
After that we will start evaluating which ones are too far from the current user view.
*/
if (warmingUpCounter < WARM_UP_LIMIT) {
warmingUpCounter++
return false
}
let radarFactor = 2 // How big is the margin
/* If the chain parent is not far, they we dont consither this far. */
@@ -117,9 +88,11 @@ function newFloatingSpace () {
/* Exceptions that are never considered far. */
if (
payload.node.type === 'Definition' ||
payload.node.type === 'Trading System' ||
payload.node.type === 'Network' ||
payload.node.type === 'Team'
payload.node.type === 'Crypto Ecosystem' ||
payload.node.type === 'Charting Space' ||
payload.node.type === 'Data Mine'
) {
return false
}
@@ -272,7 +245,7 @@ function newFloatingSpace () {
}
function physics () {
if (visible === true || warmingUpCounter < WARM_UP_LIMIT) {
if (visible === true) {
browserZoomPhysics()
thisObject.floatingLayer.physics()
}
+234 -66
View File
@@ -8,6 +8,8 @@ function newPanelsSpace () {
let thisObject = {
visible: true,
container: undefined,
makeVisible: makeVisible,
makeInvisible: makeInvisible,
createNewPanel: createNewPanel,
destroyPanel: destroyPanel,
getPanel: getPanel,
@@ -23,10 +25,8 @@ function newPanelsSpace () {
thisObject.container = container
thisObject.container.isDraggeable = false
container.displacement.containerName = 'Panels Space'
container.frame.containerName = 'Panels Space'
panelsMap = new Map()
return thisObject
function initialize () {
@@ -35,58 +35,65 @@ function newPanelsSpace () {
}
function createNewPanel (pType, pParameters, pOwner, pSession, pPanelCode) {
function createNewPanel (pType, pParameters, pOwner, pSession) {
let panel
switch (pType) {
case 'Time Control Panel':
case 'Layers Panel':
{
panel = newTimeControlPanel()
panel.initialize()
break
}
case 'Products Panel':
{
panel = newProductsPanel()
panel.fitFunction = canvas.chartSpace.fitIntoVisibleArea
panel = newLayersPanel()
panel.fitFunction = canvas.chartSpace.fitFunction
panel.container.isVisibleFunction = canvas.chartSpace.isThisPointVisible
panel.type = 'Layers Panel'
break
}
case 'Plotter Panel':
{
if (pPanelCode !== undefined) {
if (pParameters.panelNode.code.isLegacy !== true) {
panel = newPlotterPanel()
panel.fitFunction = canvas.chartSpace.fitIntoVisibleArea
panel.fitFunction = canvas.chartSpace.fitFunction
panel.container.isVisibleFunction = canvas.chartSpace.isThisPointVisible
panel.session = pSession
panel.initialize(pPanelCode)
panel.initialize(pParameters.panelNode)
} else {
panel = getNewPlotterPanel(pParameters.devTeam, pParameters.plotterCodeName, pParameters.moduleCodeName, pParameters.panelCodeName)
panel.fitFunction = canvas.chartSpace.fitIntoVisibleArea
panel = getNewPlotterPanel(pParameters.dataMine, pParameters.plotterCodeName, pParameters.moduleCodeName, pParameters.panelNode.code.codeName)
panel.fitFunction = canvas.chartSpace.fitFunction
panel.container.isVisibleFunction = canvas.chartSpace.isThisPointVisible
panel.session = pSession
panel.initialize()
}
panel.type = 'Plotter Panel'
break
}
}
let panelArray = panelsMap.get(pOwner)
if (panelArray === undefined) {
panelArray = []
panelsMap.set(pOwner, panelArray)
}
panelArray.push(panel)
panel.owner = pOwner
thisObject.panels.push(panel)
panel.handle = Math.floor((Math.random() * 10000000) + 1)
return panel.handle
}
function makeVisible (owner, type) {
for (let i = 0; i < thisObject.panels.length; i++) {
let panel = thisObject.panels[i]
if (panel.owner === owner && panel.type === type) {
panel.isVisible = true
}
}
}
function makeInvisible (owner, type) {
for (let i = 0; i < thisObject.panels.length; i++) {
let panel = thisObject.panels[i]
if (panel.owner === owner && panel.type === type) {
panel.isVisible = false
}
}
}
function destroyPanel (pPanelHandle) {
for (let i = 0; i < thisObject.panels.length; i++) {
let panel = thisObject.panels[i]
@@ -102,15 +109,12 @@ function newPanelsSpace () {
}
}
function getPanel (pPanelHandle, pOwner) {
thisObject.panels = panelsMap.get(pOwner)
if (thisObject.panels != undefined) {
for (let i = 0; i < thisObject.panels.length; i++) {
let panel = thisObject.panels[i]
function getPanel (pPanelHandle) {
for (let i = 0; i < thisObject.panels.length; i++) {
let panel = thisObject.panels[i]
if (panel.handle === pPanelHandle) {
return panel
}
if (panel.handle === pPanelHandle) {
return panel
}
}
}
@@ -118,33 +122,203 @@ function newPanelsSpace () {
function physics () {
if (thisObject.visible !== true) { return }
childrenPhysics()
positioningPhysics()
}
function childrenPhysics () {
if (thisObject.panels !== undefined) {
for (let i = 0; i < thisObject.panels.length; i++) {
let panel = thisObject.panels[i]
if (panel.physics !== undefined) {
panel.physics()
let owner = canvas.chartSpace.inViewport.get(panel.owner)
if (owner !== undefined) {
if (panel.physics !== undefined) {
panel.physics()
}
}
}
}
}
function positioningPhysics () {
if (thisObject.panels !== undefined) {
for (let i = 0; i < thisObject.panels.length; i++) {
let panel = thisObject.panels[i]
/* setting the speed of the panel */
if (panel.container.speed === undefined) {
panel.container.speed = {
x: 2,
y: 2
}
}
/* Trying to move the panel and see if it is possible */
let centerPoint = {
x: panel.container.frame.position.x,
y: panel.container.frame.position.y
}
centerPoint.x = centerPoint.x + panel.container.frame.width / 2
centerPoint.y = centerPoint.y + panel.container.frame.height / 2
/* Lets see which quadrant the panel is at */
let verticalLine = (canvas.chartSpace.viewport.visibleArea.topRight.x - canvas.chartSpace.viewport.visibleArea.topLeft.x) / 2 + canvas.chartSpace.viewport.visibleArea.topLeft.x
let horizontalLine = (canvas.chartSpace.viewport.visibleArea.bottomRight.y - canvas.chartSpace.viewport.visibleArea.topRight.y) / 2 + canvas.chartSpace.viewport.visibleArea.topRight.y
if (panel.panelTabButton !== undefined) {
if (panel.panelTabButton.status === 'up') {
if (centerPoint.x < verticalLine) {
panel.gravitatesTowards = 'topLeft'
} else {
panel.gravitatesTowards = 'topRight'
}
} else {
if (centerPoint.x < verticalLine) {
panel.gravitatesTowards = 'bottomLeft'
} else {
panel.gravitatesTowards = 'bottomRight'
}
}
} else {
if (centerPoint.x < verticalLine && centerPoint.y < horizontalLine) {
panel.gravitatesTowards = 'topLeft'
}
if (centerPoint.x >= verticalLine && centerPoint.y < horizontalLine) {
panel.gravitatesTowards = 'topRight'
}
if (centerPoint.x < verticalLine && centerPoint.y >= horizontalLine) {
panel.gravitatesTowards = 'bottomLeft'
}
if (centerPoint.x >= verticalLine && centerPoint.y >= horizontalLine) {
panel.gravitatesTowards = 'bottomRight'
}
}
/* According to the quadrant we push the panels to the sides */
if (panel.gravitatesTowards === 'topLeft' || panel.gravitatesTowards === 'bottomLeft') {
panel.container.frame.position.x = panel.container.frame.position.x - panel.container.speed.x
isOverlapping(i, panel.container)
if (panel.container.frame.position.x < 0) {
panel.container.frame.position.x = 0
}
} else {
panel.container.frame.position.x = panel.container.frame.position.x + panel.container.speed.x
isOverlapping(i, panel.container)
if (panel.container.frame.position.x + panel.container.frame.width > browserCanvas.width) {
panel.container.frame.position.x = browserCanvas.width - panel.container.frame.width
}
}
if (panel.container.frame.height <= canvas.chartSpace.viewport.visibleArea.bottomRight.y - canvas.chartSpace.viewport.visibleArea.topRight.y) {
if (panel.gravitatesTowards === 'topLeft' || panel.gravitatesTowards === 'topRight') {
panel.container.frame.position.y = panel.container.frame.position.y - panel.container.speed.y
isOverlapping(i, panel.container)
if (panel.container.frame.position.y < canvas.chartSpace.viewport.visibleArea.topLeft.y) {
panel.container.frame.position.y = canvas.chartSpace.viewport.visibleArea.topLeft.y
}
} else {
panel.container.frame.position.y = panel.container.frame.position.y + panel.container.speed.y
isOverlapping(i, panel.container)
if (panel.container.frame.position.y + panel.container.frame.height > canvas.chartSpace.viewport.visibleArea.bottomRight.y) {
panel.container.frame.position.y = canvas.chartSpace.viewport.visibleArea.bottomRight.y - panel.container.frame.height
}
}
}
}
}
function isOverlapping (currentIndex, currentContainer) {
let corner1 = {
x: currentContainer.frame.position.x,
y: currentContainer.frame.position.y
}
let corner2 = {
x: currentContainer.frame.position.x + currentContainer.frame.width,
y: currentContainer.frame.position.y
}
let corner3 = {
x: currentContainer.frame.position.x + currentContainer.frame.width,
y: currentContainer.frame.position.y + currentContainer.frame.height
}
let corner4 = {
x: currentContainer.frame.position.x,
y: currentContainer.frame.position.y + currentContainer.frame.height
}
for (let i = 0; i < currentIndex; i++) {
let panel = thisObject.panels[i]
if (panel.isVisible === true) {
if (isThisPointInsideThisFrame(corner1, panel.container.frame) === true) {
pushOut(currentContainer, panel.container, panel.gravitatesTowards)
}
if (isThisPointInsideThisFrame(corner2, panel.container.frame) === true) {
pushOut(currentContainer, panel.container, panel.gravitatesTowards)
}
if (isThisPointInsideThisFrame(corner3, panel.container.frame) === true) {
pushOut(currentContainer, panel.container, panel.gravitatesTowards)
}
if (isThisPointInsideThisFrame(corner4, panel.container.frame) === true) {
pushOut(currentContainer, panel.container, panel.gravitatesTowards)
}
}
}
function pushOut (currentContainer, controlContainer, corner) {
switch (corner) {
case 'topLeft': {
currentContainer.frame.position.x = controlContainer.frame.position.x + controlContainer.frame.width
break
}
case 'topRight': {
currentContainer.frame.position.x = controlContainer.frame.position.x - currentContainer.frame.width
break
}
case 'bottomLeft': {
currentContainer.frame.position.x = controlContainer.frame.position.x + controlContainer.frame.width
break
}
case 'bottomRight': {
currentContainer.frame.position.x = controlContainer.frame.position.x - currentContainer.frame.width
break
}
}
}
function isThisPointInsideThisFrame (point, frame) {
let corner1 = {
x: frame.position.x,
y: frame.position.y
}
let corner2 = {
x: frame.position.x + frame.width,
y: frame.position.y
}
let corner3 = {
x: frame.position.x + frame.width,
y: frame.position.y + frame.height
}
let corner4 = {
x: frame.position.x,
y: frame.position.y + frame.height
}
if (point.x >= corner1.x && point.y >= corner1.y && point.x <= corner3.x && point.y <= corner3.y) {
return true
} else {
return false
}
}
return false
}
}
function draw () {
if (thisObject.visible !== true) { return }
thisObject.container.frame.draw(false, false)
thisObject.panels = panelsMap.get('Global')
if (thisObject.panels !== undefined) {
for (let i = 0; i < thisObject.panels.length; i++) {
let panel = thisObject.panels[i]
panel.draw()
}
}
thisObject.panels = panelsMap.get(window.CHART_ON_FOCUS)
if (thisObject.panels !== undefined) {
for (let i = 0; i < thisObject.panels.length; i++) {
let panel = thisObject.panels[i]
for (let i = 0; i < thisObject.panels.length; i++) {
let panel = thisObject.panels[i]
let owner = canvas.chartSpace.inViewport.get(panel.owner)
if (owner !== undefined) {
panel.draw()
}
}
@@ -154,26 +328,20 @@ function newPanelsSpace () {
if (thisObject.visible !== true) { return }
let container
/*
We search for the container of panels in the oposite direction than we do it for drawing them,
so panels overlapping others are picked firt although they are drawn last.
*/
if (thisObject.panels !== undefined) {
for (var i = thisObject.panels.length - 1; i >= 0; i--) {
container = thisObject.panels[i].getContainer(point)
if (container !== undefined) {
/* We found an inner container which has the point. We return it. */
return container
}
/*
We search for the container of panels in the oposite direction than we do it for drawing them,
so panels overlapping others are picked firt although they are drawn last.
*/
for (let i = thisObject.panels.length - 1; i >= 0; i--) {
let panel = thisObject.panels[i]
let owner = canvas.chartSpace.inViewport.get(panel.owner)
if (owner !== undefined) {
container = panel.getContainer(point)
}
if (container !== undefined) {
return container
}
}
/* The point does not belong to any inner container, so we return the current container. */
return thisObject.container
}
}
+3 -3
View File
@@ -18,7 +18,7 @@ function newTopSpace () {
return thisObject
function initialize () {
window.canvasApp.eventHandler.listenToEvent('Browser Resized', resize)
canvas.eventHandler.listenToEvent('Browser Resized', resize)
}
function resize () {
@@ -27,7 +27,7 @@ function newTopSpace () {
container.frame.position.x = 0
try {
container.frame.position.y = viewPort.visibleArea.bottomLeft.y
container.frame.position.y = canvas.chartSpace.viewport.visibleArea.bottomLeft.y
} catch (e) { }
}
@@ -59,7 +59,7 @@ function newTopSpace () {
browserCanvasContext.beginPath()
browserCanvasContext.rect(0, 0, thisObject.container.frame.width, thisObject.container.frame.height)
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.RUSTED_RED + ', ' + opacity + ')'
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.PATINATED_TURQUOISE + ', ' + opacity + ')'
browserCanvasContext.closePath()
+5 -6
View File
@@ -19,7 +19,6 @@ function newSplashScreen () {
resize()
container.displacement.containerName = 'Splash Screen'
container.frame.containerName = 'Splash Screen'
container.frame.position.x = 0
@@ -46,7 +45,7 @@ function newSplashScreen () {
logo.src = window.canvasApp.urlPrefix + 'Images/Superalgos-logo-horz-sm-t.png'
window.canvasApp.eventHandler.listenToEvent('Browser Resized', resize)
canvas.eventHandler.listenToEvent('Browser Resized', resize)
}
function resize () {
@@ -126,7 +125,7 @@ function newSplashScreen () {
fontSize = 15
title = 'Trading Automation System'
title = 'Beta'
titlePoint = {
x: thisObject.container.frame.width / 2 - title.length / 2 * fontSize * FONT_ASPECT_RATIO - 20,
@@ -134,7 +133,7 @@ function newSplashScreen () {
}
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
browserCanvasContext.font = 'Saira'
browserCanvasContext.font = 'Saira Condensed'
browserCanvasContext.fillStyle = 'rgba(0, 0, 0, ' + opacity + ')'
browserCanvasContext.fillText(title, titlePoint.x, titlePoint.y)
}
@@ -144,14 +143,14 @@ function newSplashScreen () {
/* First we check if this point is inside this space. */
if (this.container.frame.isThisPointHere(point) === true) {
if (thisObject.container.frame.isThisPointHere(point) === true) {
/* Now we see which is the inner most container that has it */
// add validation of inner most containers here.
/* The point does not belong to any inner container, so we return the current container. */
return this.container
return thisObject.container
} else {
/* This point does not belong to this space. */
+104 -87
View File
@@ -1,3 +1,86 @@
function drawContainerBackground (container, color, opacity, fitFunction) {
let fromPoint = {
x: 0,
y: 0
}
let toPoint = {
x: container.frame.width,
y: container.frame.height
}
fromPoint = transformThisPoint(fromPoint, container)
toPoint = transformThisPoint(toPoint, container)
fromPoint = fitFunction(fromPoint)
toPoint = fitFunction(toPoint)
browserCanvasContext.beginPath()
browserCanvasContext.rect(fromPoint.x, fromPoint.y, toPoint.x - fromPoint.x, toPoint.y - fromPoint.y)
browserCanvasContext.fillStyle = 'rgba(' + color + ', ' + opacity + ')'
browserCanvasContext.closePath()
browserCanvasContext.fill()
}
function savePropertyAtNodeConfig (payload, propertyName, value) {
try {
let code = JSON.parse(payload.node.code)
code[propertyName] = value
payload.node.code = JSON.stringify(code, null, 4)
} catch (err) {
// we ignore errors here since most likely they will be parsing errors.
}
}
function loadPropertyFromNodeConfig (payload, propertyName) {
try {
let code = JSON.parse(payload.node.code)
return code[propertyName]
} catch (err) {
// we ignore errors here since most likely they will be parsing errors.
}
}
function saveFrame (payload, frame) {
payload.frame = {
position: {
x: frame.position.x,
y: frame.position.y
},
width: frame.width,
height: frame.height,
radius: frame.radius
}
}
function loadFrame (payload, frame) {
if (payload.node.savedPayload !== undefined) {
if (payload.node.savedPayload.frame !== undefined) {
frame.position.x = payload.node.savedPayload.frame.position.x
frame.position.y = payload.node.savedPayload.frame.position.y
frame.width = payload.node.savedPayload.frame.width
frame.height = payload.node.savedPayload.frame.height
frame.radius = payload.node.savedPayload.frame.radius
payload.node.savedPayload.frame = undefined
}
}
}
function convertTimeFrameToName (pTimeFrame) {
for (let i = 0; i < dailyFilePeriods.length; i++) {
let period = dailyFilePeriods[i]
if (period[0] === pTimeFrame) {
return period[1]
}
}
for (let i = 0; i < marketFilesPeriods.length; i++) {
let period = marketFilesPeriods[i]
if (period[0] === pTimeFrame) {
return period[1]
}
}
}
function download (filename, text) {
let element = document.createElement('a')
@@ -14,20 +97,15 @@ function transformThisPoint (point, container) {
point = container.frame.frameThisPoint(point)
/* We add the possible displacement */
/* We pass this point through the canvas.chartSpace.viewport lends, meaning we apply the canvas.chartSpace.viewport zoom and displacement. */
point = container.displacement.displaceThisPoint(point)
/* We viewport Transformation. */
point = viewPort.zoomThisPoint(point)
point = canvas.chartSpace.viewport.transformThisPoint(point)
return point
}
function unTransformThisPoint (point, container) {
point = viewPort.unzoomThisPoint(point)
point = container.displacement.undisplaceThisPoint(point)
point = canvas.chartSpace.viewport.unTransformThisPoint(point)
point = container.frame.unframeThisPoint(point)
return point
@@ -46,114 +124,53 @@ function pad (str, max) {
return str.length < max ? pad('0' + str, max) : str
}
function getDateFromPoint (point, container, timeLineCoordinateSystem) {
function getDateFromPoint (point, container, coordinateSystem) {
point = unTransformThisPoint(point, container)
point = timeLineCoordinateSystem.unInverseTransform(point, container.frame.height)
point = coordinateSystem.unInverseTransform(point, container.frame.height)
let date = new Date(point.x)
return date
}
function getRateFromPoint (point, container, timeLineCoordinateSystem) {
function getRateFromPoint (point, container, coordinateSystem) {
point = unTransformThisPoint(point, container)
point = timeLineCoordinateSystem.unInverseTransform(point, container.frame.height)
point = coordinateSystem.unInverseTransform(point, container.frame.height)
return point.y
}
function getMilisecondsFromPoint (point, container, timeLineCoordinateSystem) {
function getMilisecondsFromPoint (point, container, coordinateSystem) {
point = unTransformThisPoint(point, container)
point = timeLineCoordinateSystem.unInverseTransform(point, container.frame.height)
point = coordinateSystem.unInverseTransform(point, container.frame.height)
return point.x
}
function saveUserPosition (container, timeLineCoordinateSystem, position) {
if (position === undefined) {
position = {
x: (viewPort.visibleArea.bottomRight.x - viewPort.visibleArea.topLeft.x) / 2,
y: (viewPort.visibleArea.bottomRight.y - viewPort.visibleArea.topLeft.y) / 2
}
}
let userPosition = {
date: getDateFromPoint(position, container, timeLineCoordinateSystem),
rate: getRateFromPoint(position, container, timeLineCoordinateSystem),
market: DEFAULT_MARKET,
zoom: viewPort.zoomTargetLevel
}
window.localStorage.setItem('userPosition', JSON.stringify(userPosition))
}
function getUserPosition (timeLineCoordinateSystem) {
let savedPosition = window.localStorage.getItem('userPosition')
let userPosition
if (savedPosition === null) {
userPosition = {
date: (new Date()).toString(),
rate: timeLineCoordinateSystem.max.y / 2,
market: DEFAULT_MARKET,
zoom: INITIAL_ZOOM_LEVEL
}
} else {
userPosition = JSON.parse(savedPosition)
}
userPosition.point = {
x: (new Date(userPosition.date)).valueOf(),
y: userPosition.rate
}
return userPosition
}
function moveToUserPosition (container, timeLineCoordinateSystem, ignoreX, ignoreY, center, considerZoom) {
let userPosition = getUserPosition(timeLineCoordinateSystem)
if (considerZoom === true) {
viewPort.newZoomLevel(userPosition.zoom)
}
INITIAL_TIME_PERIOD = recalculatePeriod(userPosition.zoom)
NEW_SESSION_INITIAL_DATE = new Date(userPosition.date)
function moveToUserPosition (container, currentDate, currentRate, coordinateSystem, ignoreX, ignoreY, mousePosition) {
let targetPoint = {
x: (new Date(userPosition.date)).valueOf(),
y: userPosition.rate
x: currentDate.valueOf(),
y: currentRate
}
/* Put this po int in the coordinate system of the viewPort */
targetPoint = timeLineCoordinateSystem.transformThisPoint(targetPoint)
/* Put this point in the coordinate system of the canvas.chartSpace.viewport */
targetPoint = coordinateSystem.transformThisPoint(targetPoint)
targetPoint = transformThisPoint(targetPoint, container)
let centerPoint
if (center !== undefined) {
centerPoint = {
x: center.x,
y: center.y
}
} else {
centerPoint = {
x: (viewPort.visibleArea.bottomRight.x - viewPort.visibleArea.topLeft.x) / 2,
y: (viewPort.visibleArea.bottomRight.y - viewPort.visibleArea.topLeft.y) / 2
}
}
let displaceVector
/* Lets calculate the displace vector, from the point we want at the center, to the current center. */
let targetNoZoom = canvas.chartSpace.viewport.unTransformThisPoint(targetPoint)
let mouseNoZoom = canvas.chartSpace.viewport.unTransformThisPoint(mousePosition)
let displaceVector = {
x: centerPoint.x - targetPoint.x,
y: centerPoint.y - targetPoint.y
displaceVector = {
x: mouseNoZoom.x - targetNoZoom.x,
y: mouseNoZoom.y - targetNoZoom.y
}
if (ignoreX) { displaceVector.x = 0 }
if (ignoreY) { displaceVector.y = 0 }
viewPort.displace(displaceVector)
container.displace(displaceVector)
}
function removeTime (datetime) {
+35
View File
@@ -104,3 +104,38 @@ function roundedCornersBackground (params) {
browserCanvasContext.strokeStyle = 'rgba(' + params.borderColor + ', ' + params.opacity + ')'
browserCanvasContext.stroke()
}
function drawLabel (label, xFactor, yFactor, xOffset, yOffset, fontSize, container) {
if (label === undefined) { return }
let fontOffset = label.length * fontSize * FONT_ASPECT_RATIO + 10
let labelPoint = {
x: container.frame.width * xFactor + xOffset - fontOffset / 2,
y: container.frame.height * yFactor + yOffset
}
labelPoint = container.frame.frameThisPoint(labelPoint)
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', 1)'
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y)
}
function drawIcon (icon, xFactor, yFactor, xOffset, yOffset, imageSize, container) {
if (icon !== undefined) {
if (icon.canDrawIcon === true) {
let imagePosition = {
x: container.frame.width * xFactor + xOffset - imageSize / 2,
y: container.frame.height * yFactor + yOffset - imageSize / 2
}
imagePosition = container.frame.frameThisPoint(imagePosition)
browserCanvasContext.drawImage(
icon, imagePosition.x,
imagePosition.y,
imageSize,
imageSize)
}
}
}