diff --git a/Canvas.js b/Canvas.js index 8ef7e6bf9..761054077 100644 --- a/Canvas.js +++ b/Canvas.js @@ -159,13 +159,13 @@ function newCanvas () { /* Here we add all the functions that will be called during the animation cycle. */ + animation.addCallBackFunction('ViewPort Draw', viewPort.draw, onFunctionAdded) animation.addCallBackFunction('Chart Space Background', thisObject.chartSpace.drawBackground, onFunctionAdded) animation.addCallBackFunction('Chart Space', thisObject.chartSpace.draw, onFunctionAdded) animation.addCallBackFunction('Floating Space', thisObject.floatingSpace.floatingLayer.physicsLoop, onFunctionAdded) animation.addCallBackFunction('Panels Space', thisObject.panelsSpace.draw, onFunctionAdded) animation.addCallBackFunction('Splash Screen', splashScreen.draw, onFunctionAdded) animation.addCallBackFunction('ViewPort Animate', viewPort.animate, onFunctionAdded) - animation.addCallBackFunction('ViewPort Draw', viewPort.draw, onFunctionAdded) animation.addCallBackFunction('Bottom Space', thisObject.bottomSpace.draw, onFunctionAdded) animation.addCallBackFunction('Top Space', thisObject.topSpace.draw, onFunctionAdded) animation.start(onStart) diff --git a/ChartUtilities.js b/ChartUtilities.js index 6a2c91389..e7d29bd8a 100644 --- a/ChartUtilities.js +++ b/ChartUtilities.js @@ -139,4 +139,5 @@ function recalculatePeriod (zoomLevel) { if (zoomLevel <= -28) { return ONE_DAY_IN_MILISECONDS } + return ONE_DAY_IN_MILISECONDS } diff --git a/Container.js b/Container.js index 442957f08..8ea75ce14 100644 --- a/Container.js +++ b/Container.js @@ -45,6 +45,7 @@ function newContainer () { thisObject.parentContainer = parentContainer thisObject.parentContainer.eventHandler.listenToEvent('Dimmensions Changed', onParentDimmensionsChanged) thisObject.parentContainer.eventHandler.listenToEvent('onMouseOver', onMouseOver) + thisObject.parentContainer.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver) if (connectedToParentWidth) { thisObject.frame.width = thisObject.parentContainer.frame.width @@ -74,6 +75,10 @@ function newContainer () { thisObject.eventHandler.raiseEvent('onMouseOver', event) } + function onMouseNotOver (event) { + thisObject.eventHandler.raiseEvent('onMouseNotOver', event) + } + function isForThisPurpose (purpose) { if (purpose !== undefined) { switch (purpose) { diff --git a/Dashboard.js b/Dashboard.js index 1adcdea84..dcc28e5c4 100644 --- a/Dashboard.js +++ b/Dashboard.js @@ -2,8 +2,6 @@ let canvas let markets let ecosystem = newEcosystem() -let INITIAL_ZOOM_LEVEL = -26 // This is the zoom level at the view port in which the APP starts. -let INITIAL_TIME_PERIOD = recalculatePeriod(MIN_ZOOM_LEVEL) // This value will be overwritten at the viewPort.initialize if the user had a prevous session with this same browser. let viewPort = newViewPort() function newDashboard () { diff --git a/Frame.js b/Frame.js index 93a4627e0..a2a541bef 100644 --- a/Frame.js +++ b/Frame.js @@ -397,6 +397,11 @@ function newFrame () { function borders () { /* Lest get the important points of the drawing so as to apply the needed transformations. */ + let point1 + let point2 + let point3 + let point4 + point1 = { x: 0, y: 0 diff --git a/Globals.js b/Globals.js index 61cd669b2..30c706c36 100644 --- a/Globals.js +++ b/Globals.js @@ -117,6 +117,8 @@ function convertTimePeriodToName(pTimePeriod) { window.AT_BREAKPOINT = false; + + const USDT_BTC_HTH = 19900; // This is needed to know the scale of the market time line. const WIDHTER_VOLUME_BAR_BASE_FACTOR = 2.5; @@ -143,7 +145,16 @@ const _3_MINUTES_IN_MILISECONDS = 3 * 60 * 1000; const _2_MINUTES_IN_MILISECONDS = 2 * 60 * 1000; const _1_MINUTE_IN_MILISECONDS = 1 * 60 * 1000; -const EARLIEST_DATE = new Date(2014, 0, 18, 4, 26, 8); +let NEW_SESSION_INITIAL_DATE = new Date(); // This value will be overwritten at the viewPort.initialize if the user had a prevous session with this same browser. +let INITIAL_ZOOM_LEVEL = -28.25 // This is the zoom level at the view port in which the APP starts. +let INITIAL_TIME_PERIOD = ONE_DAY_IN_MILISECONDS // This value will be overwritten at the viewPort.initialize if the user had a prevous session with this same browser. + +let maxDate = new Date(); +maxDate.setMilliseconds(0); +maxDate.setDate(maxDate.getDate() + 365 * 1); // We might have charts that projects data into the future. + +const MIN_PLOTABLE_DATE = new Date(2015, 0, 1, 0, 0, 0); +const MAX_PLOTABLE_DATE = maxDate; const TOP_SPACE_HEIGHT = 5; const BOTTOM_SPACE_HEIGHT = 35; @@ -167,13 +178,9 @@ const PERIOD_10_MIN = "10-min"; const PERIOD_05_MIN = "05-min"; const PERIOD_01_MIN = "01-min"; -let INITIAL_DATE = new Date(); // This value will be overwritten at the viewPort.initialize if the user had a prevous session with this same browser. -var maxDate = new Date(); -maxDate.setMilliseconds(0); -maxDate.setDate(maxDate.getDate() + 10); -const MAX_PLOTABLE_DATE = maxDate; + /* 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. diff --git a/Panels/TimeControlPanel.js b/Panels/TimeControlPanel.js index 2a1448e4e..b56759dc3 100644 --- a/Panels/TimeControlPanel.js +++ b/Panels/TimeControlPanel.js @@ -37,7 +37,7 @@ function newTimeControlPanel () { panelTabButton.container.frame.parentFrame = thisObject.container.frame panelTabButton.initialize() - let datetime = INITIAL_DATE + let datetime = NEW_SESSION_INITIAL_DATE let datetimeDisplay = { currentDatetime: datetime, diff --git a/PlottersManager.js b/PlottersManager.js index b73fbc704..f868af859 100644 --- a/PlottersManager.js +++ b/PlottersManager.js @@ -10,7 +10,7 @@ function newPlottersManager () { let competitionPlotters = [] let timePeriod = INITIAL_TIME_PERIOD - let datetime = INITIAL_DATE + let datetime = NEW_SESSION_INITIAL_DATE let thisObject = { setDatetime: setDatetime, @@ -476,7 +476,7 @@ function newPlottersManager () { if (INFO_LOG === true) { logger.write('[INFO] initializeProductPlotter -> onProductStorageInitialized -> onPlotterInizialized -> key = ' + pProductCard.product.plotter.devTeam + '-' + pProductCard.product.plotter.codeName + '-' + pProductCard.product.plotter.moduleName) } try { - // plotter.positionAtDatetime(INITIAL_DATE); + // plotter.positionAtDatetime(NEW_SESSION_INITIAL_DATE); } catch (err) { // If the plotter does not implement this function its ok. } diff --git a/ProductCard.js b/ProductCard.js index 0dcdbd59c..15bdff06a 100644 --- a/ProductCard.js +++ b/ProductCard.js @@ -70,7 +70,7 @@ function newProductCard () { } let timePeriod = INITIAL_TIME_PERIOD - let datetime = INITIAL_DATE + 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 diff --git a/Scales/RightScale.js b/Scales/RightScale.js index c88b12ceb..2edb711f1 100644 --- a/Scales/RightScale.js +++ b/Scales/RightScale.js @@ -1,144 +1,217 @@ - function newRigthScale () { - const MODULE_NAME = 'Right Scale' - const INFO_LOG = false - const INTENSIVE_LOG = false - const ERROR_LOG = true - const logger = newWebDebugLog() - logger.fileName = MODULE_NAME +function newRigthScale () { + const MODULE_NAME = 'Right Scale' + const INFO_LOG = false + const INTENSIVE_LOG = false + const ERROR_LOG = true + const logger = newWebDebugLog() + logger.fileName = MODULE_NAME - let thisObject = { - container: undefined, - draw: draw, - getContainer: getContainer, - initialize: initialize, - heightPercentage: 100 - } + let thisObject = { + container: undefined, + draw: draw, + getContainer: getContainer, + initialize: initialize, + heightPercentage: 100 + } - const HEIGHT_PERCENTAGE_DEFAULT_VALUE = 50 - const RIGHT_MARGIN = 50 - const STEP_SIZE = 5 + const HEIGHT_PERCENTAGE_DEFAULT_VALUE = 50 + const STEP_SIZE = 5 + const MIN_WIDTH = 50 - thisObject.container = newContainer() - thisObject.container.initialize(MODULE_NAME) + thisObject.container = newContainer() + thisObject.container.initialize(MODULE_NAME) - thisObject.container.frame.width = RIGHT_MARGIN - thisObject.container.frame.height = viewPort.visibleArea.bottomRight.y - viewPort.visibleArea.topRight.y + thisObject.container.frame.width = viewPort.margins.RIGHT + thisObject.container.frame.height = viewPort.visibleArea.bottomRight.y - viewPort.visibleArea.topRight.y - thisObject.container.frame.position.x = viewPort.visibleArea.bottomRight.x - thisObject.container.frame.position.y = TOP_SPACE_HEIGHT + thisObject.container.frame.position.x = viewPort.visibleArea.bottomRight.x + thisObject.container.frame.position.y = TOP_SPACE_HEIGHT - thisObject.container.isDraggeable = false - thisObject.container.isClickeable = false - thisObject.container.isWheelable = true + thisObject.container.isDraggeable = false + thisObject.container.isClickeable = false + thisObject.container.isWheelable = true - let mouse = { - position: { - x: 0, - y: 0 - } - } + let mouse = { + position: { + x: 0, + y: 0 + } + } - return thisObject + let visible = false + let timeLineCoordinateSystem - function initialize () { - thisObject.container.eventHandler.listenToEvent('Mouse Wheel', onMouseWheel) + return thisObject - thisObject.heightPercentage = window.localStorage.getItem(MODULE_NAME) - if (!thisObject.heightPercentage) { - thisObject.heightPercentage = HEIGHT_PERCENTAGE_DEFAULT_VALUE - } else { - thisObject.heightPercentage = JSON.parse(thisObject.heightPercentage) - } + function initialize (pTimeLineCoordinateSystem) { + timeLineCoordinateSystem = pTimeLineCoordinateSystem - let event = {} - event.heightPercentage = thisObject.heightPercentage - thisObject.container.eventHandler.raiseEvent('Height Percentage Changed', event) + thisObject.container.eventHandler.listenToEvent('Mouse Wheel', onMouseWheel) - thisObject.container.eventHandler.listenToEvent('onMouseOver', function (event) { - mouse.position.x = event.x - mouse.position.y = event.y - }) - } + thisObject.heightPercentage = window.localStorage.getItem(MODULE_NAME) + if (!thisObject.heightPercentage) { + thisObject.heightPercentage = HEIGHT_PERCENTAGE_DEFAULT_VALUE + } else { + thisObject.heightPercentage = JSON.parse(thisObject.heightPercentage) + } - 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 > 100) { thisObject.heightPercentage = 100 } - } - event.heightPercentage = thisObject.heightPercentage - thisObject.container.eventHandler.raiseEvent('Height Percentage Changed', event) + let event = {} + event.heightPercentage = thisObject.heightPercentage + thisObject.container.eventHandler.raiseEvent('Height Percentage Changed', event) - window.localStorage.setItem(MODULE_NAME, thisObject.heightPercentage) - } + thisObject.container.eventHandler.listenToEvent('onMouseOver', function (event) { + mouse.position.x = event.x + mouse.position.y = event.y - function getContainer (point) { - let container + visible = true + }) - /* First we check if this point is inside this object UI. */ + thisObject.container.eventHandler.listenToEvent('onMouseNotOver', function (event) { + visible = false + }) + } - if (thisObject.container.frame.isThisPointHere(point, true) === true) { - return thisObject.container - } else { - /* This point does not belong to this space. */ + 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 > 100) { thisObject.heightPercentage = 100 } + } + event.heightPercentage = thisObject.heightPercentage + thisObject.container.eventHandler.raiseEvent('Height Percentage Changed', event) - return undefined - } - } + window.localStorage.setItem(MODULE_NAME, thisObject.heightPercentage) + } - function draw () { - drawBackground() - drawLabel() - } + function getContainer (pPoint) { + let container - function drawBackground () { - const RIGHT_MARGIN = 50 +/* In this case we manually frame this point since we do a very special treatment of the position of this scale. */ + let point = { + x: 0, + y: 0 + } + point.x = pPoint.x - thisObject.container.frame.position.x - viewPort.margins.RIGHT + point.y = pPoint.y - thisObject.container.frame.position.y - /* We will paint some transparent background here. */ + if (thisObject.container.frame.isThisPointHere(point, undefined, true) === true) { + return thisObject.container + } else { + /* This point does not belong to this space. */ - let opacity = '0.95' + return undefined + } + } - browserCanvasContext.beginPath() + function draw () { + if (visible === false) { return } - browserCanvasContext.rect(viewPort.visibleArea.topRight.x, viewPort.visibleArea.topRight.y, RIGHT_MARGIN, viewPort.visibleArea.bottomRight.y - viewPort.visibleArea.topRight.y) - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + opacity + ')' +/* 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. */ - browserCanvasContext.closePath() + let frame = thisObject.container.parentContainer.frame + let point1 + let point2 + let point3 + let point4 - browserCanvasContext.fill() - } + point1 = { + x: frame.width - frame.width / 10, + y: 0 + } - function drawLabel () { - let label = '6000' - let fontSize = 10 + point2 = { + x: frame.width, + y: 0 + } - let ratePoint = { - x: 0, - y: mouse.position.y - } + point3 = { + x: frame.width, + y: frame.height + } - // getRateFromPoint(ratePoint) + point4 = { + x: frame.width - frame.width / 10, + y: frame.height + } - let labelPoint = { - x: viewPort.visibleArea.topRight.x + 5, - y: mouse.position.y - fontSize / 2 + 1 - } + point5 = { + x: 0, + y: 0 + } - let xOffset = 0// label.length / 2 * fontSize * FONT_ASPECT_RATIO + /* Now the transformations. */ - browserCanvasContext.beginPath() + 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) - browserCanvasContext.rect(labelPoint.x, labelPoint.y, xOffset * 2, fontSize) - browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.RUSTED_RED + ', 1)' - browserCanvasContext.fill() + point1 = viewPort.fitIntoVisibleArea(point1) + point2 = viewPort.fitIntoVisibleArea(point2) + point3 = viewPort.fitIntoVisibleArea(point3) + point4 = viewPort.fitIntoVisibleArea(point4) + point5 = viewPort.fitIntoVisibleArea(point5) - browserCanvasContext.closePath() + if (point2.x - point1.x < MIN_WIDTH) { + point1.x = point2.x - MIN_WIDTH + point4.x = point2.x - MIN_WIDTH + } + + /* Lets start the drawing. */ +/* + browserCanvasContext.beginPath() + browserCanvasContext.moveTo(point1.x, point1.y) + browserCanvasContext.lineTo(point2.x + viewPort.margins.RIGHT, point2.y) + browserCanvasContext.lineTo(point3.x + viewPort.margins.RIGHT, point3.y) + browserCanvasContext.lineTo(point4.x, point4.y) + browserCanvasContext.lineTo(point1.x, point1.y) + browserCanvasContext.closePath() + + browserCanvasContext.strokeStyle = 'rgba(150, 150, 150, 1)' + browserCanvasContext.lineWidth = 1 + browserCanvasContext.stroke() +*/ + thisObject.container.frame.position.x = point1.x + thisObject.container.frame.position.y = point1.y + + thisObject.container.frame.width = point2.x - point1.x + thisObject.container.frame.height = point3.y - point2.y + + let point = { + x: point5.x + viewPort.margins.RIGHT, + y: mouse.position.y + } + + let rate = getRateFromPoint(point, thisObject.container.parentContainer, timeLineCoordinateSystem) + + let label = rate.toFixed(2) + let fontSize = 10 + + let xOffset = label.length * fontSize * FONT_ASPECT_RATIO + + if (point.y + fontSize / 2 > point3.y || point.y - fontSize / 2 < point1.y) { return } + + browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.DARK + ', 0.50)' + + browserCanvasContext.fillText(label, point1.x + viewPort.margins.RIGHT, point.y + fontSize / 2) + + browserCanvasContext.beginPath() + + browserCanvasContext.moveTo(point.x, point.y) + browserCanvasContext.lineTo(point1.x + viewPort.margins.RIGHT, point.y) + + browserCanvasContext.closePath() + + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.DARK + ', 0.5)' + browserCanvasContext.lineWidth = 0.2 + browserCanvasContext.setLineDash([1, 5]) + browserCanvasContext.stroke() + } +} - browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY - browserCanvasContext.fillStyle = 'rgba(60, 60, 60, 0.50)' - browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y) - } - } diff --git a/Scales/TimeScale.js b/Scales/TimeScale.js index 5e8dba0f1..d994e99bc 100644 --- a/Scales/TimeScale.js +++ b/Scales/TimeScale.js @@ -14,26 +14,32 @@ function newTimeScale () { lenghtPercentage: undefined } - const LENGHT_PERCENTAGE_DEFAULT_VALUE = 50 - const RIGHT_MARGIN = 50 + const LENGHT_PERCENTAGE_DEFAULT_VALUE = 5 const STEP_SIZE = 5 + const MIN_HEIGHT = 50 thisObject.container = newContainer() thisObject.container.initialize(MODULE_NAME) - thisObject.container.frame.width = viewPort.visibleArea.bottomRight.x - viewPort.visibleArea.topLeft.x - thisObject.container.frame.height = 100 - - thisObject.container.frame.position.x = viewPort.visibleArea.bottomRight.x - thisObject.container.frame.position.y = TOP_SPACE_HEIGHT - thisObject.container.isDraggeable = false thisObject.container.isClickeable = false thisObject.container.isWheelable = true + let mouse = { + position: { + x: 0, + y: 0 + } + } + + let visible = false + let timeLineCoordinateSystem + return thisObject - function initialize () { + function initialize (pTimeLineCoordinateSystem) { + timeLineCoordinateSystem = pTimeLineCoordinateSystem + thisObject.container.eventHandler.listenToEvent('Mouse Wheel', onMouseWheel) thisObject.lenghtPercentage = window.localStorage.getItem(MODULE_NAME) @@ -46,6 +52,17 @@ function newTimeScale () { let event = {} event.lenghtPercentage = thisObject.lenghtPercentage thisObject.container.eventHandler.raiseEvent('Lenght Percentage Changed', event) + + thisObject.container.eventHandler.listenToEvent('onMouseOver', function (event) { + mouse.position.x = event.x + mouse.position.y = event.y + + visible = true + }) + + thisObject.container.eventHandler.listenToEvent('onMouseNotOver', function (event) { + visible = false + }) } function onMouseWheel (event) { @@ -64,10 +81,16 @@ function newTimeScale () { window.localStorage.setItem(MODULE_NAME, thisObject.lenghtPercentage) } - function getContainer (point) { + function getContainer (pPoint) { let container - /* First we check if this point is inside this object UI. */ +/* In this case we manually frame this point since we do a very special treatment of the position of this scale. */ + let point = { + x: 0, + y: 0 + } + point.x = pPoint.x - thisObject.container.frame.position.x + point.y = pPoint.y - thisObject.container.frame.position.y + viewPort.margins.TOP if (thisObject.container.frame.isThisPointHere(point, undefined, true) === true) { return thisObject.container @@ -79,6 +102,112 @@ function newTimeScale () { } 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: 0 + } + + point2 = { + x: frame.width, + y: 0 + } + + point3 = { + x: frame.width, + y: frame.height / 10 + } + + point4 = { + x: 0, + y: frame.height / 10 + } + + point5 = { + x: 0, + y: frame.height + } + + /* Now the transformations. */ + + point1 = transformThisPoint(point1, frame.container) + point2 = transformThisPoint(point2, frame.container) + point3 = transformThisPoint(point3, frame.container) + point4 = transformThisPoint(point4, frame.container) + point5 = transformThisPoint(point5, frame.container) + + point1 = viewPort.fitIntoVisibleArea(point1) + point2 = viewPort.fitIntoVisibleArea(point2) + point3 = viewPort.fitIntoVisibleArea(point3) + point4 = viewPort.fitIntoVisibleArea(point4) + point5 = viewPort.fitIntoVisibleArea(point5) + + if (point3.y - point2.y < MIN_HEIGHT) { + point3.y = point2.y + MIN_HEIGHT + point4.y = point2.y + MIN_HEIGHT + } + + /* Lets start the drawing. */ +/* + browserCanvasContext.beginPath() + browserCanvasContext.moveTo(point1.x, point1.y - viewPort.margins.TOP) + browserCanvasContext.lineTo(point2.x, point2.y - viewPort.margins.TOP) + browserCanvasContext.lineTo(point3.x, point3.y - viewPort.margins.TOP) + browserCanvasContext.lineTo(point4.x, point4.y - viewPort.margins.TOP) + browserCanvasContext.lineTo(point1.x, point1.y - viewPort.margins.TOP) + browserCanvasContext.closePath() + + browserCanvasContext.strokeStyle = 'rgba(150, 150, 150, 1)' + browserCanvasContext.lineWidth = 1 + browserCanvasContext.stroke() +*/ + + thisObject.container.frame.position.x = point1.x + thisObject.container.frame.position.y = point1.y + + thisObject.container.frame.width = point2.x - point1.x + thisObject.container.frame.height = point3.y - point2.y + + let point = { + x: mouse.position.x, + y: point1.y - viewPort.margins.TOP + } + + let date = getDateFromPoint(point, thisObject.container, timeLineCoordinateSystem) + date = new Date(date) + + let label = date.toUTCString() + let fontSize = 10 + + let xOffset = label.length * fontSize * FONT_ASPECT_RATIO + + browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY + browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.DARK + ', 0.50)' + + if (point.x - xOffset / 2 < point1.x || point.x + xOffset / 2 > point2.x) { return } + + browserCanvasContext.fillText(label, point.x - xOffset / 2, point.y + fontSize + 7) + + browserCanvasContext.beginPath() + + browserCanvasContext.moveTo(point.x, point1.y) + browserCanvasContext.lineTo(point.x, point5.y) + + browserCanvasContext.closePath() + + browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.DARK + ', 0.5)' + browserCanvasContext.lineWidth = 0.2 + browserCanvasContext.setLineDash([1, 5]) + browserCanvasContext.stroke() } } diff --git a/TimeMachine.js b/TimeMachine.js index 75e11f84a..efbc9df25 100644 --- a/TimeMachine.js +++ b/TimeMachine.js @@ -43,6 +43,8 @@ function newTimeMachine () { let timeScale let rigthScale + let timeLineCoordinateSystem = newTimeLineCoordinateSystem() + return thisObject function finalize () { @@ -67,6 +69,13 @@ function newTimeMachine () { controlPanelHandle = canvas.panelsSpace.createNewPanel('Time Control Panel', undefined, panelOwner) let controlPanel = canvas.panelsSpace.getPanel(controlPanelHandle, panelOwner) + recalculateScale() + + thisObject.container.eventHandler.listenToEvent('Dimmensions Changed', function (event) { + recalculateScale() + moveToUserPosition(thisObject.container, timeLineCoordinateSystem, false, false, event.mousePosition) + }) + /* First, we initialize the market that we are going to show first on screen. Later all the other markets will be initialized on the background. */ let position = 0 // This defines the position of each chart respect to each other. @@ -74,7 +83,6 @@ function newTimeMachine () { let timelineChart = newTimelineChart() timelineChart.container.connectToParent(thisObject.container, true, true) - timelineChart.container.frame.height = thisObject.container.frame.height timelineChart.container.frame.position.x = thisObject.container.frame.width / 2 - timelineChart.container.frame.width / 2 @@ -82,7 +90,7 @@ function newTimeMachine () { position++ - timelineChart.initialize(DEFAULT_EXCHANGE, DEFAULT_MARKET, onDefaultInitialized) + timelineChart.initialize(DEFAULT_EXCHANGE, DEFAULT_MARKET, timeLineCoordinateSystem, onDefaultInitialized) function onDefaultInitialized (err) { if (err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { @@ -98,22 +106,22 @@ function newTimeMachine () { /* Each Time Machine has a Time Scale and a Right Scale. */ timeScale = newTimeScale() - + timeScale.container.connectToParent(thisObject.container, false, false) timeScale.container.eventHandler.listenToEvent('Lenght Percentage Changed', function (event) { thisObject.container.frame.width = TIME_MACHINE_WIDTH * event.lenghtPercentage / 100 thisObject.container.eventHandler.raiseEvent('Dimmensions Changed', event) }) - timeScale.initialize() + timeScale.initialize(timeLineCoordinateSystem) rigthScale = newRigthScale() - + rigthScale.container.connectToParent(thisObject.container, false, false) rigthScale.container.eventHandler.listenToEvent('Height Percentage Changed', function (event) { thisObject.container.frame.height = TIME_MACHINE_HEIGHT * event.heightPercentage / 100 thisObject.container.eventHandler.raiseEvent('Dimmensions Changed', event) }) - rigthScale.initialize() + rigthScale.initialize(timeLineCoordinateSystem) initializeTheRest() } @@ -158,7 +166,7 @@ function newTimeMachine () { position++ - timelineChart.initialize(exchange, market, finalSteps) + timelineChart.initialize(exchange, market, timeLineCoordinateSystem, finalSteps) function finalSteps () { if (INFO_LOG === true) { logger.write('[INFO] initialize -> initializeTheRest -> initializeTimelineChart -> finalSteps -> Entering function.') } @@ -186,15 +194,17 @@ function newTimeMachine () { } function draw () { - // this.container.frame.draw(false, false) + 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 < this.charts.length; i++) { - let chart = this.charts[i] - chart.draw() + if (timeScale !== undefined) { timeScale.draw() } + if (rigthScale !== undefined) { rigthScale.draw() } + + // thisObject.container.frame.draw(false, true, false) } - - if (timeScale !== undefined) { timeScale.draw() } - if (rigthScale !== undefined) { rigthScale.draw() } } function getContainer (point, purpose) { @@ -226,6 +236,35 @@ function newTimeMachine () { } } } - return this.container + + if (thisObject.container.frame.isThisPointHere(point) === true) { + return thisObject.container + } else { + if (purpose === GET_CONTAINER_PURPOSE.MOUSE_OVER) { + thisObject.container.eventHandler.raiseEvent('onMouseNotOver') + } + return + } + } + + function recalculateScale () { + if (INFO_LOG === true) { logger.write('[INFO] recalculateScale -> Entering function.') } + + let minValue = { + x: MIN_PLOTABLE_DATE.valueOf(), + y: 0 + } + + let maxValue = { + x: MAX_PLOTABLE_DATE.valueOf(), + y: nextPorwerOf10(USDT_BTC_HTH) / 4 + } + + timeLineCoordinateSystem.initialize( + minValue, + maxValue, + thisObject.container.frame.width, + thisObject.container.frame.height + ) } } diff --git a/TimelineChart.js b/TimelineChart.js index da21b21be..bc42bb917 100644 --- a/TimelineChart.js +++ b/TimelineChart.js @@ -6,10 +6,10 @@ const logger = newWebDebugLog() logger.fileName = MODULE_NAME - let timeLineCoordinateSystem = newTimeLineCoordinateSystem() + let timeLineCoordinateSystem let timePeriod = INITIAL_TIME_PERIOD - let datetime = INITIAL_DATE + let datetime = NEW_SESSION_INITIAL_DATE let thisObject = { setDatetime: setDatetime, @@ -60,22 +60,18 @@ } } - function initialize (pExchange, pMarket, callBackFunction) { + function initialize (pExchange, pMarket, pTimeLineCoordinateSystem, callBackFunction) { try { if (INFO_LOG === true) { logger.write('[INFO] initialize -> Entering function.') } - thisObject.container.eventHandler.listenToEvent('Dimmensions Changed', function (event) { - recalculateScale() - moveToUserPosition(thisObject.container, timeLineCoordinateSystem, false, false, event.mousePosition) - }) - - thisObject.container.eventHandler.listenToEvent('onMouseOver', function (event) { - saveUserPosition(thisObject.container, timeLineCoordinateSystem, event) - }) - /* We load the logow we will need for the background. */ exchange = pExchange market = pMarket + timeLineCoordinateSystem = pTimeLineCoordinateSystem + + thisObject.container.eventHandler.listenToEvent('onMouseOver', function (event) { + saveUserPosition(thisObject.container, timeLineCoordinateSystem, event) + }) let panelOwner = exchange + ' ' + market.assetB + '/' + market.assetA productsPanelHandle = canvas.panelsSpace.createNewPanel('Products Panel', undefined, panelOwner) @@ -122,11 +118,9 @@ breakpointsBar = newBreakpointsBar() breakpointsBar.initialize(thisObject.container, timeLineCoordinateSystem) - recalculateScale() - - moveToUserPosition(thisObject.container, timeLineCoordinateSystem) + // moveToUserPosition(thisObject.container, timeLineCoordinateSystem, undefined, undefined, undefined, true) timePeriod = INITIAL_TIME_PERIOD - datetime = INITIAL_DATE + datetime = NEW_SESSION_INITIAL_DATE /* Event Subscriptions - we need this events to be fired first here and then in active Plotters. */ @@ -253,27 +247,6 @@ return container } - function recalculateScale () { - if (INFO_LOG === true) { logger.write('[INFO] recalculateScale -> Entering function.') } - - let minValue = { - x: EARLIEST_DATE.valueOf(), - y: 0 - } - - let maxValue = { - x: MAX_PLOTABLE_DATE.valueOf(), - y: nextPorwerOf10(USDT_BTC_HTH) / 4 - } - - timeLineCoordinateSystem.initialize( - minValue, - maxValue, - thisObject.container.frame.width, - thisObject.container.frame.height - ) - } - function tooTiny () { if (INTENSIVE_LOG === true) { logger.write('[INFO] tooTiny -> Entering function.') } @@ -301,8 +274,6 @@ if (window.CHART_ON_FOCUS === '') { window.CHART_ON_FOCUS = exchange + ' ' + market.assetB + '/' + market.assetA - this.container.frame.draw() - drawChartsBackgroundImages() } } @@ -333,7 +304,7 @@ } let toPoint = { - x: 0, + x: thisObject.container.frame.width, y: thisObject.container.frame.height } @@ -342,7 +313,7 @@ browserCanvasContext.beginPath() - browserCanvasContext.rect(viewPort.visibleArea.topLeft.x, fromPoint.y, viewPort.visibleArea.topRight.x - viewPort.visibleArea.topLeft.x, toPoint.y - fromPoint.y) + browserCanvasContext.rect(fromPoint.x, fromPoint.y, toPoint.x - fromPoint.x, toPoint.y - fromPoint.y) browserCanvasContext.fillStyle = 'rgba(' + UI_COLOR.WHITE + ', ' + opacity + ')' browserCanvasContext.closePath() @@ -355,6 +326,23 @@ if (canDrawLogoA === false || canDrawLogoB === false || canDrawLogoExchange === false || canDrawLogoAA === false) { return } + /* Fist we calculate the corners of the current frame so as not to draw imaages ourside of it */ + + let fromPoint = { + x: 0, + y: 0 + } + + let toPoint = { + x: thisObject.container.frame.width, + y: thisObject.container.frame.height + } + + fromPoint = transformThisPoint(fromPoint, thisObject.container) + toPoint = transformThisPoint(toPoint, thisObject.container) + + /* Second we calculate the points for the images themselves */ + let backgroundLogoPoint1 let backgroundLogoPoint2 @@ -398,6 +386,10 @@ 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) { @@ -409,7 +401,17 @@ for (let i = 0; i < MAX_COLUMNS; i = i + 4) { let logo = logoA - browserCanvasContext.drawImage(logo, imagePoint.x + i * imageWidth * 2 + offSet, imagePoint.y + j * rowHight + Y_TOP_MARGIN, imageWidth, imageHeight) + imagePosition.x = imagePoint.x + i * imageWidth * 2 + offSet + imagePosition.y = imagePoint.y + j * rowHight + Y_TOP_MARGIN + + if ( + imagePosition.x > fromPoint.x && + imagePosition.x + imageWidth < toPoint.x && + imagePosition.y > fromPoint.y && + imagePosition.y + imageHeight < toPoint.y + ) { + browserCanvasContext.drawImage(logo, imagePosition.x, imagePosition.y, imageWidth, imageHeight) + } } } @@ -425,7 +427,17 @@ for (let i = 1; i < MAX_COLUMNS; i = i + 4) { let logo = logoB - browserCanvasContext.drawImage(logo, imagePoint.x + i * imageWidth * 2 + offSet, imagePoint.y + j * rowHight + Y_TOP_MARGIN, imageWidth, imageHeight) + imagePosition.x = imagePoint.x + i * imageWidth * 2 + offSet + imagePosition.y = imagePoint.y + j * rowHight + Y_TOP_MARGIN + + if ( + imagePosition.x > fromPoint.x && + imagePosition.x + imageWidth < toPoint.x && + imagePosition.y > fromPoint.y && + imagePosition.y + imageHeight < toPoint.y + ) { + browserCanvasContext.drawImage(logo, imagePosition.x, imagePosition.y, imageWidth, imageHeight) + } } } @@ -441,7 +453,17 @@ for (let i = 2; i < MAX_COLUMNS; i = i + 4) { let logo = logoExchange - browserCanvasContext.drawImage(logo, imagePoint.x + i * imageWidth * 2 + offSet, imagePoint.y + j * rowHight + Y_TOP_MARGIN, imageWidth, imageHeight) + imagePosition.x = imagePoint.x + i * imageWidth * 2 + offSet + imagePosition.y = imagePoint.y + j * rowHight + Y_TOP_MARGIN + + if ( + imagePosition.x > fromPoint.x && + imagePosition.x + imageWidth < toPoint.x && + imagePosition.y > fromPoint.y && + imagePosition.y + imageHeight < toPoint.y + ) { + browserCanvasContext.drawImage(logo, imagePosition.x, imagePosition.y, imageWidth, imageHeight) + } } } @@ -457,7 +479,17 @@ for (let i = 3; i < MAX_COLUMNS; i = i + 4) { let logo = logoAA - browserCanvasContext.drawImage(logo, imagePoint.x + i * imageWidth * 2 + offSet, imagePoint.y + j * rowHight + Y_TOP_MARGIN, imageWidth, imageHeight) + imagePosition.x = imagePoint.x + i * imageWidth * 2 + offSet + imagePosition.y = imagePoint.y + j * rowHight + Y_TOP_MARGIN + + if ( + imagePosition.x > fromPoint.x && + imagePosition.x + imageWidth < toPoint.x && + imagePosition.y > fromPoint.y && + imagePosition.y + imageHeight < toPoint.y + ) { + browserCanvasContext.drawImage(logo, imagePosition.x, imagePosition.y, imageWidth, imageHeight) + } } } } diff --git a/Utilities.js b/Utilities.js index 2ea30bde1..cffc22713 100644 --- a/Utilities.js +++ b/Utilities.js @@ -100,12 +100,15 @@ function getUserPosition (timeLineCoordinateSystem) { return userPosition } -function moveToUserPosition (container, timeLineCoordinateSystem, ignoreX, ignoreY, center) { +function moveToUserPosition (container, timeLineCoordinateSystem, ignoreX, ignoreY, center, considerZoom) { let userPosition = getUserPosition(timeLineCoordinateSystem) - viewPort.newZoomLevel(userPosition.zoom) + if (considerZoom === true) { + viewPort.newZoomLevel(userPosition.zoom) + } + INITIAL_TIME_PERIOD = recalculatePeriod(userPosition.zoom) - INITIAL_DATE = new Date(userPosition.date) + NEW_SESSION_INITIAL_DATE = new Date(userPosition.date) let targetPoint = { x: (new Date(userPosition.date)).valueOf(), @@ -150,4 +153,3 @@ function removeTime (datetime) { return dateOnly } - diff --git a/ViewPort.js b/ViewPort.js index e45fc54c8..70d4aeae1 100644 --- a/ViewPort.js +++ b/ViewPort.js @@ -1,5 +1,12 @@  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 let ANIMATION_INCREMENT = 0.25 @@ -7,6 +14,12 @@ function newViewPort () { const BOTTOM_MARGIN = 15 + BOTTOM_SPACE_HEIGHT const LEFT_MARGIN = 50 const RIGHT_MARGIN = 50 + const MARGINS = { + TOP: TOP_MARGIN, + BOTTOM: BOTTOM_MARGIN, + LEFT: LEFT_MARGIN, + RIGHT: RIGHT_MARGIN + } let thisObject = { visibleArea: undefined, @@ -14,6 +27,7 @@ function newViewPort () { zoomTargetLevel: undefined, zoomLevel: undefined, mousePosition: undefined, + margins: MARGINS, getDisplacement: getDisplacement, newZoomLevel: newZoomLevel, applyZoom: applyZoom, @@ -55,6 +69,8 @@ function newViewPort () { thisObject.eventHandler = newEventHandler() + let objectStorage = {} + return thisObject function initialize () { @@ -64,6 +80,8 @@ function newViewPort () { bottomRight: { x: browserCanvas.width - RIGHT_MARGIN, y: browserCanvas.height - BOTTOM_MARGIN}, bottomLeft: { x: LEFT_MARGIN, y: browserCanvas.height - BOTTOM_MARGIN} } + + readObjectState() } function getDisplacement () { @@ -99,17 +117,6 @@ function newViewPort () { changeZoom(thisObject.zoomLevel + ANIMATION_INCREMENT, thisObject.zoomLevel) } - /* - if (offsetIncrement.x !== 0) { - - if (Math.trunc(Math.abs(targetOffset.x - offset.x) * 1000) >= Math.trunc(Math.abs(offsetIncrement.x) * 1000)) { - offset.x = offset.x + offsetIncrement.x; - } else { - offsetIncrement.x = 0; - } - } -*/ - 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 @@ -125,6 +132,8 @@ function newViewPort () { offset.x = offset.x + displaceVector.x offset.y = offset.y + displaceVector.y + saveObjectState() + let event = { newOffset: offset } @@ -150,6 +159,8 @@ function newViewPort () { thisObject.zoomTargetLevel = level thisObject.zoomLevel = level + saveObjectState() + ANIMATION_INCREMENT = Math.abs(thisObject.zoomTargetLevel - thisObject.zoomLevel) / 3 let event = { @@ -244,6 +255,8 @@ function newViewPort () { 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 @@ -332,22 +345,21 @@ function newViewPort () { } function draw () { -/* - drawGrid(10); - drawGrid(1); - drawGrid(0.1); -*/ + 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 = 10 / step + 10 / step * increment * thisObject.zoomLevel + let lineWidth = 0.4 + thisObject.zoomLevel / 100 + lineWidth = lineWidth.toFixed(2) - if (lineWidth < 0.5) { + if (lineWidth < 0.1) { return } @@ -357,40 +369,66 @@ function newViewPort () { browserCanvasContext.beginPath() - for (var i = startingX; i < thisObject.visibleArea.bottomRight.x; i = i + squareWidth) { - for (var j = startingY; j < thisObject.visibleArea.bottomRight.y; j = j + squareWidth) { + 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: thisObject.visibleArea.bottomLeft.x, - y: j + x: Math.trunc(i - CROSS_SIZE), + y: Math.trunc(j) } let point2 = { - x: thisObject.visibleArea.bottomRight.x, - y: j + 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: i, - y: thisObject.visibleArea.topLeft.y - } + let point3 = { + x: Math.trunc(i), + y: Math.trunc(j - CROSS_SIZE) + } - let point4 = { - x: i, - y: thisObject.visibleArea.bottomLeft.y - } + 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.moveTo(point3.x, point3.y) + browserCanvasContext.lineTo(point4.x, point4.y) + } } browserCanvasContext.closePath() - browserCanvasContext.strokeStyle = 'rgba(150, 150, 150, 0.' + Math.trunc(lineWidth + 1) + ')' + browserCanvasContext.strokeStyle = 'rgba(150, 150, 150, 0.5)' - browserCanvasContext.lineWidth = lineWidth + browserCanvasContext.lineWidth = 1 browserCanvasContext.stroke() } + + function saveObjectState () { + objectStorage.offset = offset + objectStorage.zoomLevel = thisObject.zoomLevel + 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) + 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 + } + thisObject.zoomLevel = MIN_ZOOM_LEVEL + thisObject.zoomTargetLevel = MIN_ZOOM_LEVEL + } + } }