Improvements on positioning in the timeline when openning the app

Now the app will try to re position itself on the timeline at the last place visited with the same zoom level. This will not be possible only when it is the first time the app is usued or when the screen resolution was changed, in both cases the positionning will be at the current datetime.
This commit is contained in:
Luis Fernando Molina committed 2018-05-15 15:38:47 +02:00
1 parent 6cb6de2c00
commit 07f8795ae6
7 files changed
+211 -83

No files matched your search

+13 -5
View File
@@ -86,17 +86,25 @@ function newCanvas() {
let panelsSpace = newPanelsSpace();
panelsSpace.initialize();
this.panelsSpace = panelsSpace;
thisObject.panelsSpace = panelsSpace;
let floatingSpace = newFloatingSpace();
floatingSpace.initialize();
this.floatingSpace = floatingSpace;
thisObject.floatingSpace = floatingSpace;
let chartSpace = newChartSpace();
chartSpace.initialize();
chartSpace.initialize(onCharSpaceInitialized);
this.chartSpace = chartSpace;
thisObject.chartSpace = chartSpace;
function onCharSpaceInitialized(err) {
viewPort.raiseEvents(); // These events will impacts on objects just initialized.
/* We will store the last used this screen resolution. This will help us know if we can remember the las viewPort offset or not, since they depends on the screen resolution. */
window.localStorage.setItem('webApp.lastRun.screenResolution', browserCanvas.width + '.' + browserCanvas.height);
}
/* Splash Screen */
@@ -108,7 +116,7 @@ function newCanvas() {
function onAnimationInitialized(err) {
this.animation = animation;
thisObject.animation = animation;
/* Here we add all the functions that will be called during the animation cycle. */
+2 -6
View File
@@ -129,7 +129,7 @@ const FONT_ASPECT_RATIO = 0.60;
const CHART_ASPECT_RATIO = 1 / 10;
const INITIAL_ZOOM_LEVEL = -22; // This is the zoom level at the view port in which the APP starts.
const INITIAL_TIME_PERIOD = recalculatePeriod(INITIAL_ZOOM_LEVEL);
let INITIAL_TIME_PERIOD = recalculatePeriod(INITIAL_ZOOM_LEVEL); // This value will be overwritten at the viewPort.initialize if the user had a prevous session with this same browser.
var viewPort = newViewPort();
@@ -153,11 +153,7 @@ const PERIOD_10_MIN = "10-min";
const PERIOD_05_MIN = "05-min";
const PERIOD_01_MIN = "01-min";
var newDate = new Date();
newDate.setMilliseconds(0);
newDate.setDate(newDate.getDate() - 90);
const INITIAL_DATE = new Date();
const 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);
+16 -1
View File
@@ -86,8 +86,21 @@ function newTimeControlPanel() {
thisObject.buttons = buttons;
let datetime = INITIAL_DATE;
var datetime = INITIAL_DATE;
/* There is a chance that we could resume the last session at the place we left it. */
let lastRun = window.localStorage.getItem('webApp.lastRun.screenResolution');
if (lastRun !== null && lastRun === browserCanvas.width + '.' + browserCanvas.height) {
let savedCurrentDatetime = window.localStorage.getItem('timeControlPanel.currentDatetime');
if (savedCurrentDatetime !== null) {
datetime = new Date(savedCurrentDatetime);
}
}
var datetimeDisplay = {
currentDatetime: datetime,
@@ -153,6 +166,8 @@ function newTimeControlPanel() {
thisObject.datetimeDisplay.currentDatetime = newDatetime;
window.localStorage.setItem('timeControlPanel.currentDatetime', newDatetime);
}
+36 -13
View File
@@ -13,7 +13,7 @@ function newChartSpace() {
const logger = newDebugLog();
logger.fileName = MODULE_NAME;
var chartSpace = {
var thisObject = {
container: undefined,
draw: draw,
timeMachines: [],
@@ -24,25 +24,28 @@ function newChartSpace() {
var container = newContainer();
container.initialize();
chartSpace.container = container;
thisObject.container = container;
chartSpace.container.frame.width = browserCanvas.width * 1000;
chartSpace.container.frame.height = browserCanvas.height * 100;
thisObject.container.frame.width = browserCanvas.width * 1000;
thisObject.container.frame.height = browserCanvas.height * 100;
container.displacement.containerName = "Chart Space";
container.frame.containerName = "Chart Space";
container.frame.position.x = browserCanvas.width / 2 - chartSpace.container.frame.width / 2;
container.frame.position.y = browserCanvas.height / 2 - chartSpace.container.frame.height / 2;
container.frame.position.x = browserCanvas.width / 2 - thisObject.container.frame.width / 2;
container.frame.position.y = browserCanvas.height / 2 - thisObject.container.frame.height / 2;
container.isDraggeable = false;
return chartSpace;
return thisObject;
function initialize() {
function initialize(callBackFunction) {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> Entering function."); }
let initializedCounter = 0;
let toInitialize = 1;
/* We create the first of many possible time machines that could live at the Chart Space. */
var timeMachine = newTimeMachine();
@@ -60,21 +63,41 @@ function newChartSpace() {
timeMachine.container.frame.position.x = this.container.frame.width / 2 - timeMachine.container.frame.width / 2;
timeMachine.container.frame.position.y = this.container.frame.height / 2 - timeMachine.container.frame.height / 2;
timeMachine.initialize();
timeMachine.initialize(onTimeMachineInitialized);
this.timeMachines.push(timeMachine);
function onTimeMachineInitialized(err) {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onTimeMachineInitialized -> Entering function."); }
initializedCounter++;
if (err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onTimeMachineInitialized -> Initialization of a Time Machine failed."); }
callBackFunction(err);
return;
}
thisObject.timeMachines.push(timeMachine);
if (initializedCounter === toInitialize) {
callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE);
}
}
}
function draw() {
chartSpace.container.frame.draw(false, false);
thisObject.container.frame.draw(false, false);
/* When we draw the chart space, that means we draw all the time machines in it. */
for (var i = 0; i < chartSpace.timeMachines.length; i++ ) {
for (var i = 0; i < thisObject.timeMachines.length; i++ ) {
var timeMachine = chartSpace.timeMachines[i];
var timeMachine = thisObject.timeMachines[i];
timeMachine.draw();
}
+13 -3
View File
@@ -37,7 +37,7 @@ function newTimeMachine() {
return thisObject;
function initialize() {
function initialize(callBackFunction) {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> Entering function."); }
@@ -70,16 +70,26 @@ function newTimeMachine() {
iteration++;
function onDefaultMarketInitialized() {
function onDefaultMarketInitialized(err) {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onDefaultMarketInitialized -> Entering function."); }
if (err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onDefaultMarketInitialized -> Initialization of the only market failed."); }
callBackFunction(err);
return;
}
thisObject.charts.push(timelineChart);
controlPanel.container.eventHandler.listenToEvent('Datetime Changed', timelineChart.setDatetime, undefined);
timelineChart.container.eventHandler.listenToEvent('Datetime Changed', controlPanel.setDatetime);
initializeTheRestOfTheMarkets();
callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE);
//initializeTheRestOfTheMarkets();
}
+21 -6
View File
@@ -65,8 +65,16 @@
chartGrid = newChartGrid();
recalculateScale();
moveViewPortToCurrentDatetime();
/* When the Web App has never run, we need to position the viewPort at the current Date. This in turn will set the current date as the date for loading the data. */
let lastRun = window.localStorage.getItem('webApp.lastRun.screenResolution');
if (lastRun === null || lastRun !== browserCanvas.width + '.' + browserCanvas.height) {
moveViewPortToCurrentDatetime();
}
/* Event Subscriptions - we need this events to be fired first here and then in active Plotters. */
viewPort.eventHandler.listenToEvent("Offset Changed", onOffsetChanged);
@@ -117,7 +125,7 @@
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onCompetitionPlottersInitialized -> onProductPlottersInitialized -> Received OK Response."); }
initializationReady = true;
callBackFunction(GLOBAL.CUSTOM_OK_RESPONSE);
callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE);
break;
}
@@ -496,10 +504,17 @@
if (INFO_LOG === true) { logger.write("[INFO] initializeProductPlotter -> onProductStorageInitialized -> onPlotterInizialized -> Entering function."); }
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);
} catch (err) {
// If the plotter does not implement this function its ok.
/* When the Web App has never run, we need to position the viewPort at the current Date. Otherwise it will get automatically positioned at the last thing the user was browsing. */
let lastRun = window.localStorage.getItem('webApp.lastRun.screenResolution');
if (lastRun === null || lastRun !== browserCanvas.width + '.' + browserCanvas.height) {
try {
plotter.positionAtDatetime(INITIAL_DATE);
} catch (err) {
// If the plotter does not implement this function its ok.
}
}
let productPlotter = {
+110 -49
View File
@@ -9,10 +9,10 @@ function newViewPort() {
const LEFT_MARGIN = 50;
const RIGHT_MARGIN = 50;
let viewPort = {
let thisObject = {
visibleArea: undefined,
eventHandler: undefined,
zoomLevel: INITIAL_ZOOM_LEVEL,
zoomLevel: undefined,
mousePosition: undefined,
applyZoom: applyZoom,
zoomFontSize: zoomFontSize,
@@ -24,11 +24,10 @@ function newViewPort() {
displaceTarget: displaceTarget,
animate: animate,
draw: draw,
raiseEvents: raiseEvents,
initialize: initialize
};
zoomTargetLevel = INITIAL_ZOOM_LEVEL;
let increment = 0.035;
var offset = {
@@ -46,42 +45,93 @@ function newViewPort() {
y: 0
};
viewPort.mousePosition = {
thisObject.mousePosition = {
x: 0,
y: 0
};
viewPort.eventHandler = newEventHandler();
thisObject.eventHandler = newEventHandler();
return viewPort;
let zoomTargetLevel;
return thisObject;
function initialize() {
viewPort.visibleArea = {
thisObject.visibleArea = {
topLeft: { x: LEFT_MARGIN, y: TOP_MARGIN },
topRight: { x: browserCanvas.width - RIGHT_MARGIN , y: TOP_MARGIN },
bottomRight: { x: browserCanvas.width - RIGHT_MARGIN, y: browserCanvas.height - BOTTOM_MARGIN},
bottomLeft: { x: LEFT_MARGIN, y: browserCanvas.height - BOTTOM_MARGIN}
};
/* There is a chance that we could resume the last session at the place we left it. */
let lastRun = window.localStorage.getItem('webApp.lastRun.screenResolution');
if (lastRun !== null && lastRun === browserCanvas.width + '.' + browserCanvas.height) {
/* We get from the local storage the recored values of Zoom and OffSet during the last session using this app with this browser */
let savedZoomTargetLevel = window.localStorage.getItem('viewPort.zoomTargetLevel');
if (savedZoomTargetLevel !== null) {
thisObject.zoomLevel = Number(savedZoomTargetLevel);
zoomTargetLevel = Number(savedZoomTargetLevel);
INITIAL_TIME_PERIOD = recalculatePeriod(thisObject.zoomLevel);
}
let savedOffset = window.localStorage.getItem('viewPort.offset');
if (savedOffset !== null) {
offset = JSON.parse(savedOffset);
}
let savedTargetOffset = window.localStorage.getItem('viewPort.targetOffset');
if (savedTargetOffset !== null) {
targetOffset = JSON.parse(savedTargetOffset);
}
} else {
thisObject.zoomLevel = INITIAL_ZOOM_LEVEL;
zoomTargetLevel = INITIAL_ZOOM_LEVEL;
INITIAL_TIME_PERIOD = recalculatePeriod(thisObject.zoomLevel);
}
}
function raiseEvents() {
let event = {
newOffset: offset
};
thisObject.eventHandler.raiseEvent("Offset Changed", event);
}
function animate() {
if (viewPort.zoomLevel < zoomTargetLevel) {
if (zoomTargetLevel - viewPort.zoomLevel < ANIMATION_INCREMENT) {
ANIMATION_INCREMENT = Math.abs(zoomTargetLevel - viewPort.zoomLevel);
if (thisObject.zoomLevel < zoomTargetLevel) {
if (zoomTargetLevel - thisObject.zoomLevel < ANIMATION_INCREMENT) {
ANIMATION_INCREMENT = Math.abs(zoomTargetLevel - thisObject.zoomLevel);
}
viewPort.zoomLevel = viewPort.zoomLevel + ANIMATION_INCREMENT;
changeZoom(viewPort.zoomLevel - ANIMATION_INCREMENT, viewPort.zoomLevel);
thisObject.zoomLevel = thisObject.zoomLevel + ANIMATION_INCREMENT;
changeZoom(thisObject.zoomLevel - ANIMATION_INCREMENT, thisObject.zoomLevel);
}
if (viewPort.zoomLevel > zoomTargetLevel) {
if (viewPort.zoomLevel - zoomTargetLevel < ANIMATION_INCREMENT) {
ANIMATION_INCREMENT = Math.abs(zoomTargetLevel - viewPort.zoomLevel);
if (thisObject.zoomLevel > zoomTargetLevel) {
if (thisObject.zoomLevel - zoomTargetLevel < ANIMATION_INCREMENT) {
ANIMATION_INCREMENT = Math.abs(zoomTargetLevel - thisObject.zoomLevel);
}
viewPort.zoomLevel = viewPort.zoomLevel - ANIMATION_INCREMENT;
changeZoom(viewPort.zoomLevel + ANIMATION_INCREMENT, viewPort.zoomLevel);
thisObject.zoomLevel = thisObject.zoomLevel - ANIMATION_INCREMENT;
changeZoom(thisObject.zoomLevel + ANIMATION_INCREMENT, thisObject.zoomLevel);
}
/*
@@ -119,7 +169,9 @@ function newViewPort() {
newOffset: offset
};
viewPort.eventHandler.raiseEvent("Offset Changed", event);
thisObject.eventHandler.raiseEvent("Offset Changed", event);
window.localStorage.setItem('viewPort.offset', JSON.stringify(offset));
//console.log("displace produced new Offset x = " + offset.x + " y = " + offset.y);
@@ -137,6 +189,8 @@ function newViewPort() {
y: (targetOffset.y - offset.y) / 10
};
window.localStorage.setItem('viewPort.targetOffset', JSON.stringify(targetOffset));
//console.log("displaceTarget x = " + targetOffset.x + " y = " + targetOffset.y);
}
@@ -195,7 +249,7 @@ function newViewPort() {
zoomTargetLevel = zoomTargetLevel + amount;
ANIMATION_INCREMENT = Math.abs(zoomTargetLevel - viewPort.zoomLevel) / 3;
ANIMATION_INCREMENT = Math.abs(zoomTargetLevel - thisObject.zoomLevel) / 3;
let event = {
newLevel: zoomTargetLevel,
@@ -211,24 +265,31 @@ function newViewPort() {
//console.log("Zoom Changed > " + event.newLevel);
viewPort.eventHandler.raiseEvent("Zoom Changed", event);
thisObject.eventHandler.raiseEvent("Zoom Changed", event);
window.localStorage.setItem('viewPort.zoomTargetLevel', zoomTargetLevel);
return true;
}
function changeZoom(oldLevel, newLevel) {
let mouseNoZoom = unzoomThisPoint(viewPort.mousePosition, oldLevel);
let mouseNoZoom = unzoomThisPoint(thisObject.mousePosition, oldLevel);
let newMouse = zoomThisPoint(mouseNoZoom, newLevel);
offset.x = offset.x - newMouse.x + viewPort.mousePosition.x;
offset.y = offset.y - newMouse.y + viewPort.mousePosition.y;
offset.x = offset.x - newMouse.x + thisObject.mousePosition.x;
offset.y = offset.y - newMouse.y + thisObject.mousePosition.y;
window.localStorage.setItem('viewPort.offset', JSON.stringify(offset));
//console.log("changeZoom produced new Offset x = " + offset.x + " y = " + offset.y);
targetOffset.x = offset.x
targetOffset.y = offset.y ;
window.localStorage.setItem('viewPort.targetOffset', JSON.stringify(targetOffset));
offsetIncrement = {
x: 0,
y: 0
@@ -239,11 +300,11 @@ function newViewPort() {
function zoomFontSize(baseSize, level) {
let zoomFactor = increment; // + increment * viewPort.zoomLevel / 100;
let zoomFactor = increment; // + increment * thisObject.zoomLevel / 100;
if (level === undefined) {
baseSize = baseSize * (1 + zoomFactor * viewPort.zoomLevel);
baseSize = baseSize * (1 + zoomFactor * thisObject.zoomLevel);
} else {
@@ -259,20 +320,20 @@ function newViewPort() {
/* Here we check the boundaries of the resulting points, so they dont go out of the visible area. */
if (point.x > viewPort.visibleArea.bottomRight.x + 1) {
point.x = viewPort.visibleArea.bottomRight.x + 1;
if (point.x > thisObject.visibleArea.bottomRight.x + 1) {
point.x = thisObject.visibleArea.bottomRight.x + 1;
}
if (point.x < viewPort.visibleArea.topLeft.x - 1) {
point.x = viewPort.visibleArea.topLeft.x - 1;
if (point.x < thisObject.visibleArea.topLeft.x - 1) {
point.x = thisObject.visibleArea.topLeft.x - 1;
}
if (point.y > viewPort.visibleArea.bottomRight.y + 1) {
point.y = viewPort.visibleArea.bottomRight.y + 1;
if (point.y > thisObject.visibleArea.bottomRight.y + 1) {
point.y = thisObject.visibleArea.bottomRight.y + 1;
}
if (point.y < viewPort.visibleArea.topLeft.y - 1) {
point.y = viewPort.visibleArea.topLeft.y - 1;
if (point.y < thisObject.visibleArea.topLeft.y - 1) {
point.y = thisObject.visibleArea.topLeft.y - 1;
}
return point;
@@ -281,12 +342,12 @@ function newViewPort() {
function zoomThisPoint(point, level) {
let zoomFactor = increment; // + increment * viewPort.zoomLevel / 100;
let zoomFactor = increment; // + increment * thisObject.zoomLevel / 100;
if (level === undefined) {
point.x = point.x * (1 + zoomFactor * viewPort.zoomLevel) + offset.x;
point.y = point.y * (1 + zoomFactor * viewPort.zoomLevel) + offset.y;
point.x = point.x * (1 + zoomFactor * thisObject.zoomLevel) + offset.x;
point.y = point.y * (1 + zoomFactor * thisObject.zoomLevel) + offset.y;
} else {
@@ -301,13 +362,13 @@ function newViewPort() {
function unzoomThisPoint(pointWithZoom, level) {
let pointWithoutZoom;
let zoomFactor = increment; // + increment * viewPort.zoomLevel / 100;
let zoomFactor = increment; // + increment * thisObject.zoomLevel / 100;
if (level === undefined) {
pointWithoutZoom = {
x: (pointWithZoom.x - offset.x) / (1 + zoomFactor * viewPort.zoomLevel),
y: (pointWithZoom.y - offset.y) / (1 + zoomFactor * viewPort.zoomLevel)
x: (pointWithZoom.x - offset.x) / (1 + zoomFactor * thisObject.zoomLevel),
y: (pointWithZoom.y - offset.y) / (1 + zoomFactor * thisObject.zoomLevel)
};
} else {
@@ -352,12 +413,12 @@ function newViewPort() {
function drawGrid(step) {
let squareWidth = (viewPort.visibleArea.bottomRight.x - viewPort.visibleArea.bottomLeft.x) / step;
squareWidth = squareWidth + squareWidth * increment * viewPort.zoomLevel;
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 * viewPort.zoomLevel;
let lineWidth = 10 / step + 10 / step * increment * thisObject.zoomLevel;
if (lineWidth < 0.5) {
return;
@@ -369,17 +430,17 @@ function newViewPort() {
browserCanvasContext.beginPath();
for (var i = startingX; i < viewPort.visibleArea.bottomRight.x; i = i + squareWidth) {
for (var i = startingX; i < thisObject.visibleArea.bottomRight.x; i = i + squareWidth) {
for (var j = startingY; j < viewPort.visibleArea.bottomRight.y; j = j + squareWidth) {
for (var j = startingY; j < thisObject.visibleArea.bottomRight.y; j = j + squareWidth) {
let point1 = {
x: viewPort.visibleArea.bottomLeft.x,
x: thisObject.visibleArea.bottomLeft.x,
y: j
};
let point2 = {
x: viewPort.visibleArea.bottomRight.x,
x: thisObject.visibleArea.bottomRight.x,
y: j
};
@@ -389,12 +450,12 @@ function newViewPort() {
let point3 = {
x: i,
y: viewPort.visibleArea.topLeft.y
y: thisObject.visibleArea.topLeft.y
};
let point4 = {
x: i,
y: viewPort.visibleArea.bottomLeft.y
y: thisObject.visibleArea.bottomLeft.y
};
browserCanvasContext.moveTo(point3.x, point3.y);