diff --git a/client/components/control/control.css b/client/components/control/control.css
index 702b3c7..1cdf07f 100644
--- a/client/components/control/control.css
+++ b/client/components/control/control.css
@@ -1,6 +1,6 @@
.control-global{
- width: 30px;
- height: 30px;
+ width: 28px;
+ height: 28px;
border: 1px solid dimgray;
box-sizing: border-box;
transition: border 0.25s;
diff --git a/client/components/states_indicator/dates/dates.js b/client/components/states_indicator/dates/dates.js
index 543d59e..63ccd24 100644
--- a/client/components/states_indicator/dates/dates.js
+++ b/client/components/states_indicator/dates/dates.js
@@ -1,18 +1,40 @@
class DatesIndicator extends HTMLElement{
- constructor(oldestTimestamp, newestTimestamp){
+ constructor(timestamp){
super();
- this.oldestDate = this.timestampToString(oldestTimestamp);
- this.newestDate = this.timestampToString(newestTimestamp);
+ this.formattedDate = this.timestampToString(timestamp);
+ }
+
+ dayNumberToName(dayNumber){
+ switch(dayNumber){
+ case 0:
+ return "Sun";
+ case 1:
+ return "Mon";
+ case 2:
+ return "Tue";
+ case 3:
+ return "Wed";
+ case 4:
+ return "Thu";
+ case 5:
+ return "Fri";
+ case 6:
+ return "Sat";
+ }
}
timestampToString(timestamp){
let date = new Date(timestamp);
- return date.toUTCString();
+ let dayName = this.dayNumberToName(date.getDay());
+ let day = date.getDate();
+ let month = date.getMonth();
+ let year = date.getFullYear();
+
+ return dayName + ", " + day.toString().padStart(2, "0") + "/" + month.toString().padStart(2, "0") + "/" + year ;
}
- update(oldestTimestamp, newestTimestamp){
- this.oldestDate = this.timestampToString(oldestTimestamp);
- this.newestDate = this.timestampToString(newestTimestamp);
+ update(timestamp){
+ this.formattedDate = this.timestampToString(timestamp);
this.render()
}
@@ -24,9 +46,7 @@ class DatesIndicator extends HTMLElement{
this.innerHTML = `
- ${this.oldestDate}
- ->
- ${this.newestDate}
+ ${this.formattedDate}
`
}
diff --git a/client/cssFiles/SEAWebClientGraphics.css b/client/cssFiles/SEAWebClientGraphics.css
index 2760d91..84cad61 100644
--- a/client/cssFiles/SEAWebClientGraphics.css
+++ b/client/cssFiles/SEAWebClientGraphics.css
@@ -7,20 +7,21 @@
justify-content: flex-end;
}
-.panel.graphics span{
- margin: 0 1em;
+.panel.graphics span:first-child{
+ display: none;
+ /* margin: 0 1em;
display: flex;
user-select: none;
- -webkit-user-select: none;
+ -webkit-user-select: none; */
}
-.panel.graphics div{
+/* .panel.graphics div{
margin-left: 1em;
cursor: pointer;
-}
+} */
#control_bar{
- height: 100%;
+ height: 28px;
background-color: dimgray;
border-top-left-radius: 12px;
border-top-right-radius: 12px;
@@ -28,7 +29,8 @@
padding-right: 12px;
display: flex;
column-gap: 5px;
- margin-left: 100px;
+ margin-left: 120px;
+ margin-top: 2px;
}
/*********************/
diff --git a/client/cssFiles/SEAWebClientSwiper.css b/client/cssFiles/SEAWebClientSwiper.css
index 7538cec..ee3a515 100644
--- a/client/cssFiles/SEAWebClientSwiper.css
+++ b/client/cssFiles/SEAWebClientSwiper.css
@@ -24,12 +24,15 @@
text-align: center;
background-color: #303030;
color: white;
- padding: 6px 6px 6px 6px;
+ /* padding: 6px 6px 6px 6px; */
position: absolute;
z-index: 20;
width: 100%;
height: 30px;
}
+.panel:not(.graphics){
+ padding: 6px 6px 6px 6px;
+}
.slide-close-icon {
transition: 0.4s;
diff --git a/client/jsFiles/SEAWebClientGraphics.js b/client/jsFiles/SEAWebClientGraphics.js
index e6fbc89..bdad279 100644
--- a/client/jsFiles/SEAWebClientGraphics.js
+++ b/client/jsFiles/SEAWebClientGraphics.js
@@ -217,26 +217,21 @@ let globalControls = (function (){
function loadControls(panel){
let controlBar = document.createElement("div");
- controlBar.id = "control_bar"
+ controlBar.id = "control_bar";
panel.appendChild(controlBar);
let jumpControl = new Control("res/jump.png", "res/jump_blocked.png", "Jump", dummyCallback);
- let goToNowControl = new Control("res/go_to_now.png", "res/go_to_now_blocked.png", "Go to now", dummyCallback);
+ let goToNowControl = new Control("res/go_to_now.png", "res/go_to_now_blocked.png", "Go to now", graphs.gotoNow);
- let zoomInControl = new Control("res/zoom_in.png", "res/zoom_in_blocked.png", "Zoom in", dummyCallback);
- let zoomOutControl = new Control("res/zoom_out.png", "res/zoom_out_blocked.png", "Zoon out", dummyCallback);
- let shiftOlderControl = new Control("res/shift_older.png", "res/shift_older_blocked.png", "Shift to older", dummyCallback);
- let shiftNewerControl = new Control("res/shift_newer.png", "res/shift_newer_blocked.png", "Shift to newer", dummyCallback);
+ let zoomInControl = new Control("res/zoom_in.png", "res/zoom_in_blocked.png", "Zoom in (time)", graphs.zoomIn);
+ let zoomOutControl = new Control("res/zoom_out.png", "res/zoom_out_blocked.png", "Zoon out (time)", graphs.zoomOut);
+ let shiftOlderControl = new Control("res/shift_older.png", "res/shift_older_blocked.png", "Shift to older", graphs.shiftOlder);
+ let shiftNewerControl = new Control("res/shift_newer.png", "res/shift_newer_blocked.png", "Shift to newer", graphs.shiftNewer);
- let xyControl = new Control("res/y_direction.png", "res/x_direction.png", "Time<->Y zoom", dummyCallback, dummyCallback);
- let cursorControl = new Control("res/remove_cursor.png", "res/remove_cursor_blocked.png", "Remove cursor",dummyCallback);
- let legendsControl = new Control("res/display_legends.png", "res/remove_legends.png", "Legends", dummyCallback, dummyCallback);
-
- let now = Date.now();
- let old = now - 1000*3600;
- let dates = new DatesIndicator(old, now);
- let liveState = new LiveStateIndicator();
+ let xyControl = new Control("res/y_direction.png", "res/x_direction.png", "Time<->Y zoom (one graph)", graphs.toggleZoomMode, graphs.toggleZoomMode);
+ let cursorControl = new Control("res/remove_cursor.png", "res/remove_cursor_blocked.png", "Remove cursor", graphs.removeCursor);
+ let legendsControl = new Control("res/display_legends.png", "res/remove_legends.png", "Legends", graphs.displayAllLegends, graphs.hideAllLegends);
controlBar.appendChild(jumpControl)
controlBar.appendChild(goToNowControl)
@@ -253,12 +248,6 @@ let globalControls = (function (){
controlBar.appendChild(legendsControl);
legendsControl.changeToAlt();
- panel.appendChild(dates)
- panel.appendChild(liveState);
- liveState.changeToDisable();
- liveState.style.marginLeft = "auto"; //sticks element to the right
- dates.style.marginLeft = "auto";
-
controlsMap[jumpKey] = jumpControl;
controlsMap[goToNowKey] = goToNowControl;
controlsMap[zoomInKey] = zoomInControl;
@@ -267,7 +256,7 @@ let globalControls = (function (){
controlsMap[shiftNewerKey] = shiftNewerControl;
controlsMap[xyKey] = xyControl;
controlsMap[cursorKey] = cursorControl;
- controlsMap[legendsKey] = legendsControl;
+ controlsMap[legendsKey] = legendsControl;
}
function getControlsMap(){
@@ -280,6 +269,39 @@ let globalControls = (function (){
}
})();
+let datesKey = "dates-indicator";
+let liveKey = "live-indicator";
+
+let globalIndicators = (function (){
+
+ let indicatorsMap = {}
+
+ function loadIndicators(panel){
+ let leftDate = Date.now() - 30*60*1000;
+ let datesIndicator = new DatesIndicator(leftDate);
+ let liveIndicator = new LiveStateIndicator();
+
+ panel.appendChild(datesIndicator);
+ panel.appendChild(liveIndicator);
+ liveIndicator.changeToDisable();
+ liveIndicator.style.marginLeft = "auto"; //sticks element to the right
+ datesIndicator.style.marginLeft = "auto";
+
+ indicatorsMap[datesKey] = datesIndicator;
+ indicatorsMap[liveKey] = liveIndicator;
+ }
+
+ function getIndicatorsMap(){
+ return indicatorsMap;
+ }
+
+ return {
+ loadIndicators: loadIndicators,
+ getIndicatorsMap: getIndicatorsMap
+ }
+
+})()
+
let graphs = (function (){
let dataset_to_graph_map = {}; // a dictionnary mapping a variable name to a two values array, containing its graph index and its position inside the graph
let blocks, liveMode=true, top_vars=[], bottom_vars=[];
@@ -305,6 +327,8 @@ let graphs = (function (){
let resolution = undefined;
+ let created = false;
+
let container = document.createElement('div');
container.classList.add("graphs-container");
@@ -398,11 +422,17 @@ let graphs = (function (){
* @param {boolean} mode - Tells if we are in live mode or not
*/
function setLiveMode(mode=null) {
- if (mode !== null) liveMode = mode;
+ if (mode !== null){
+ liveMode = mode;
+ if(mode) globalIndicators.getIndicatorsMap()[liveKey].changeToEnable();
+ else globalIndicators.getIndicatorsMap()[liveKey].changeToDisable();
+ }
if (liveMode && cursorLinePos === null)
- gotoNowElm.innerHTML = '';
+ // gotoNowElm.innerHTML = '';
+ globalControls.getControlsMap()[goToNowKey].changeToAlt();
else
- gotoNowElm.innerHTML = 'go to now';
+ // gotoNowElm.innerHTML = 'go to now';
+ globalControls.getControlsMap()[goToNowKey].changeToMain();
}
/**
@@ -564,6 +594,7 @@ let graphs = (function (){
function setMinMax(min, max){
currentMaxTime = max;
currentMinTime = min;
+ globalIndicators.getIndicatorsMap()[datesKey].update(currentMinTime);
for (let gr of graph_array) {
if (gr) gr.setMinMax(min, max);
}
@@ -594,7 +625,8 @@ let graphs = (function (){
legendFlag = true;
let trect = evt.target.getBoundingClientRect();
let X = evt.clientX - trect.x, Y = evt.clientY - trect.y;
- showLegends(true, false);
+ displayAllLegends();
+ // showLegends(true, false);
cursorLine(X);
setLiveMode();
update();
@@ -720,6 +752,36 @@ let graphs = (function (){
}
}
+ function zoomIn(){
+ console.log("Zoomed in !");
+
+ let someGraph = graph_array[0];
+ let xTk = someGraph.chart.options.scales.xAxes[0].ticks;
+ let pZoom = 0.2; //window width for the zoom (a proportion of the current window, centered)
+ let delta = (xTk.max - xTk.min)*pZoom/2;
+ xTk.max -= delta;
+ xTk.min += delta;
+
+ if (liveMode && xTk.max < lastTime) setLiveMode(false);
+ setMinMax(xTk.min, xTk.max);
+ updateAuto();
+ }
+
+ function zoomOut(){
+ console.log("Zoomed out !");
+
+ let someGraph = graph_array[0];
+ let xTk = someGraph.chart.options.scales.xAxes[0].ticks;
+ let pZoom = 0.2; //window width for the zoom (a proportion of the current window, centered)
+ let delta = (xTk.max - xTk.min)*pZoom/2;
+ xTk.max += delta;
+ xTk.min -= delta;
+
+ if (liveMode && xTk.max < lastTime) setLiveMode(false);
+ setMinMax(xTk.min, xTk.max);
+ updateAuto();
+ }
+
/**
* Function called at each mouse wheel step.
* If zoom mode in x mode, disables liveMode if the visualisaiton window is older than the last known value and sets axis min and max
@@ -778,6 +840,32 @@ let graphs = (function (){
resolution = Math.ceil((timeDelta / container.getBoundingClientRect().width)/1000)
}
+ function shiftOlder(){
+
+ let someGraph = graph_array[0];
+ let xTk = someGraph.chart.options.scales.xAxes[0].ticks;
+ let pShift = 0.2; //shift size the pan (a proportion of the current window)
+ let delta = (xTk.max - xTk.min)*pShift;
+ xTk.max -= delta;
+ xTk.min -= delta;
+ if (liveMode && xTk.max < lastTime) setLiveMode(false);
+ setMinMax(xTk.min,xTk.max);
+ updateAuto();
+ }
+
+ function shiftNewer(){
+
+ let someGraph = graph_array[0];
+ let xTk = someGraph.chart.options.scales.xAxes[0].ticks;
+ let pShift = 0.2; //shift size the pan (a proportion of the current window)
+ let delta = (xTk.max - xTk.min)*pShift;
+ xTk.max += delta;
+ xTk.min += delta;
+ if (liveMode && xTk.max < lastTime) setLiveMode(false);
+ setMinMax(xTk.min,xTk.max);
+ updateAuto();
+ }
+
/**
* The function called when the viewing window is moved by the mouse.
*
@@ -826,6 +914,7 @@ let graphs = (function (){
*/
function gotoNow() {
cursorLine(null);
+ globalControls.getControlsMap()[cursorKey].changeToAlt();
if (!liveMode) {
setMinMax(graphs.now() - (currentMaxTime - currentMinTime), graphs.now());
}
@@ -877,51 +966,58 @@ let graphs = (function (){
activateUpdates();
- container.parentNode.querySelector('.panel').classList.add('graphics');
+ let graphicsPanel = container.parentNode.querySelector('.panel')
+ graphicsPanel.classList.add('graphics');
+ if(!created){
+ globalControls.loadControls(graphicsPanel);
+ globalIndicators.loadIndicators(graphicsPanel);
+ }
+
- gotoNowElm.addEventListener('click', gotoNow);
+
+ // gotoNowElm.addEventListener('click', gotoNow);
//gotoNowElm.innerHTML = "go to now";
- container.parentNode.querySelector('.panel span').appendChild(gotoNowElm);
+ // container.parentNode.querySelector('.panel span').appendChild(gotoNowElm);
// Removes the cursor then applies the changes
- function removeCursor(evt=null) {
- graphs.cursorLine(null);
- graphs.update();
- }
+ // function removeCursor(evt=null) {
+ // graphs.cursorLine(null);
+ // graphs.update();
+ // }
if (isTouchDevice) {
doubleTap(removeCursor);
} else {
window.addEventListener('dblclick', removeCursor);
showLegends(true, false);
adjustLegends();
- let zoomMode = document.createElement('div');
+ // let zoomMode = document.createElement('div');
/**
* Sets the HTML button for the y-zoom depending on the current mode
*/
- function setInnerZoomMode(){
- if (currentZoomMode == 'y') {
- zoomMode.innerHTML = "☒ y-zoom";
- } else {
- zoomMode.innerHTML = "☐ y-zoom";
- }
- prevTime = null; // reset zoom speed time
- }
- setInnerZoomMode();
+ // function setInnerZoomMode(){
+ // if (currentZoomMode == 'y') {
+ // zoomMode.innerHTML = "☒ y-zoom";
+ // } else {
+ // zoomMode.innerHTML = "☐ y-zoom";
+ // }
+ // prevTime = null; // reset zoom speed time
+ // }
+ // setInnerZoomMode();
/**
* Inverts the zoom mode (x<->y)
*/
- function toggleZoomMode(){
- if (currentZoomMode == 'y')
- currentZoomMode = 'x';
- else
- currentZoomMode = 'y';
- setInnerZoomMode();
- for (let gr of graph_array) {
- if (gr) gr.setZoomMode(currentZoomMode);
- }
- }
- zoomMode.addEventListener('click', toggleZoomMode);
- container.parentNode.querySelector('.panel span').appendChild(zoomMode);
+ // function toggleZoomMode(){
+ // if (currentZoomMode == 'y')
+ // currentZoomMode = 'x';
+ // else
+ // currentZoomMode = 'y';
+ // setInnerZoomMode();
+ // for (let gr of graph_array) {
+ // if (gr) gr.setZoomMode(currentZoomMode);
+ // }
+ // }
+ // zoomMode.addEventListener('click', toggleZoomMode);
+ // container.parentNode.querySelector('.panel span').appendChild(zoomMode);
}
// The cross to display "main" panel at the location of the graphs
@@ -943,7 +1039,39 @@ let graphs = (function (){
console.log("MAIN")
currentSwiper.slideNext();
});
- container.parentNode.querySelector('.panel span').appendChild(gotoMainElm);
+ // container.parentNode.querySelector('.panel span').appendChild(gotoMainElm);
+ if(!created){
+ graphicsPanel.appendChild(gotoMainElm);
+ created = true;
+ }
+ }
+
+
+ function setInnerZoomMode(){
+ if (currentZoomMode == 'y') {
+ globalControls.getControlsMap()[xyKey].changeToAlt();
+ } else {
+ globalControls.getControlsMap()[xyKey].changeToMain();
+ }
+ prevTime = null; // reset zoom speed time
+ }
+
+ // Callbacks
+ function toggleZoomMode(){
+ if (currentZoomMode == 'y')
+ currentZoomMode = 'x';
+ else
+ currentZoomMode = 'y';
+ setInnerZoomMode();
+ for (let gr of graph_array) {
+ if (gr) gr.setZoomMode(currentZoomMode);
+ }
+ }
+
+ function removeCursor(evt=null) {
+ graphs.cursorLine(null);
+ globalControls.getControlsMap()[cursorKey].changeToAlt();
+ graphs.update();
}
/**
@@ -981,6 +1109,16 @@ let graphs = (function (){
//bringToFront(null);
}
+ function displayAllLegends(){
+ showLegends(true, false);
+ globalControls.getControlsMap()[legendsKey].changeToAlt();
+ }
+
+ function hideAllLegends(){
+ showLegends(false, false);
+ globalControls.getControlsMap()[legendsKey].changeToMain();
+ }
+
/**
* Adjust the legend window depending on the position of the last legend
*/
@@ -1080,6 +1218,7 @@ let graphs = (function (){
cursorElement.style.display = 'block';
cursorElement.style.left = (cursorLinePos - 1) + 'px';
cursorElement.style.height = window.innerHeight + 'px';
+ globalControls.getControlsMap()[cursorKey].changeToMain();
}
return cursorLinePos;
}
@@ -1141,6 +1280,16 @@ let graphs = (function (){
setLiveMode: setLiveMode,
cursorLine: cursorLine,
bringToFront: bringToFront,
+ // Exposing callbacks for controls and indicators
+ gotoNow: gotoNow,
+ displayAllLegends: displayAllLegends,
+ hideAllLegends: hideAllLegends,
+ toggleZoomMode: toggleZoomMode,
+ removeCursor: removeCursor,
+ zoomOut: zoomOut,
+ zoomIn: zoomIn,
+ shiftOlder: shiftOlder,
+ shiftNewer: shiftNewer,
}
})();
@@ -1484,6 +1633,7 @@ function Graph(gindex, container, x_label, y_label, tag, scaleType = "linear"){
} else {
graphs.cursorLine(null);
legend.style.display = 'none';
+ globalControls.getControlsMap()[legendsKey].changeToMain();
}
}