Updated client documentation

This commit is contained in:
l_samenv
2024-09-10 11:32:24 +02:00
parent 784d3f16fc
commit 601ebf67ee
4 changed files with 67 additions and 29 deletions

View File

@ -53,10 +53,4 @@ class Control extends HTMLElement{
}
}
customElements.define("sea-control", Control)
/*
connectedCallback : called when first added
disconnectedCallback : called when removed
attributeChangedCallback : called when attribute changes. attribute to be added in observedAttributes
*/
customElements.define("sea-control", Control)

View File

@ -7,7 +7,7 @@ class CurvesSettingsPopup extends HTMLElement{
initTable(){
let userConfiguration = getUserConfiguration();
let userConfiguration = getUserConfiguration(); //located in SEAWebClientLocalStorage.js
let tbody = this.querySelector("#curves-settings-popup-table tbody");
tbody.innerHTML = "";
@ -25,7 +25,7 @@ class CurvesSettingsPopup extends HTMLElement{
let formattedUserConfiguration = this.getFormattedUserConfiguration(localStorageBuffer);
localStorage.clear();
saveUserConfiguration(localStorageBuffer);
saveUserConfiguration(localStorageBuffer); //located in SEAWebClientLocalStorage.js
this.hide();
this.applySettingsCallback(formattedUserConfiguration);

View File

@ -96,6 +96,7 @@ function AJAX(addr){
});
}
// arguments are passed like param1=value1&param2=value2...
this.postForm = function(args){
xhr.open("POST", addr, true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
@ -241,6 +242,9 @@ let globalControls = (function (){
let datesPopup = undefined;
/**
* Used to add the Dates Popup (initialization + adding it to the DOM)
*/
function loadDatesPopup(){
let graphsContainer = document.getElementsByClassName("graphs-container")[0];
datesPopup = new DatesPopup(graphs.gotoNow, graphs.jumpToDate);
@ -288,6 +292,10 @@ let globalIndicators = (function (){
let menuGraphicsPopup = undefined;
/**
* Defines all the entries in the menu and adds it to the DOM
* @param {*} panel The panel on which to add the menu icon
*/
function loadGraphicsMenu(panel){
menuGraphicsPopup = new MenuPopup();
@ -344,12 +352,18 @@ function loadGraphicsMenu(panel){
let exportPopup = undefined;
/**
* Used to add the export Popup (initialization + adding it to the DOM)
*/
function loadExportPopup(){
let graphsContainer = document.getElementsByClassName("graphs-container")[0];
exportPopup = new ExportPopup(exportCallback);
graphsContainer.appendChild(exportPopup);
}
/**
* Function call when the Export button is clicked in the Export popup
*/
function exportCallback(selectedVariables, startDateTimeMs, endDateTimeMs, nan, binning=null){
let binningParam = "None";
@ -364,6 +378,9 @@ function exportCallback(selectedVariables, startDateTimeMs, endDateTimeMs, nan,
let curvesSettingsPopup = undefined;
/**
* Used to add the curves settings Popup (initialization + adding it to the DOM)
*/
function loadCurvesSettingsPopup(){
let graphsContainer = document.getElementsByClassName("graphs-container")[0];
curvesSettingsPopup = new CurvesSettingsPopup(graphs.applySettingsCallback);
@ -1036,7 +1053,7 @@ let graphs = (function (){
});
}
// Changes the zoom mode icon depending on the current zoom mode
function setInnerZoomMode(){
if (currentZoomMode == 'y') {
globalControls.getControlsMap()[xyKey].changeToAlt();
@ -1046,7 +1063,7 @@ let graphs = (function (){
prevTime = null; // reset zoom speed time
}
// Callbacks
// Toggles the current zoom mode and sets it for each graph
function toggleZoomMode(){
if (currentZoomMode == 'y')
currentZoomMode = 'x';
@ -1241,6 +1258,11 @@ let graphs = (function (){
exportPopup.show(blocks,currentMinTime, currentMaxTime);
}
/**
* Function called when the user configuration needs to be applied.
* Calls the /getvars routes with the userconfiguration and reloads all the graphics
* @param {*} userConfiguration The JSON object representing the user configuration
*/
function applySettingsCallback(userConfiguration){
cursorLine(null);

View File

@ -1,40 +1,62 @@
The way the main page is served (where you can select the instrument you want to interact with) has not been decided yet, even if its code is in this repository.
# Client - developer documentation
### Initialization/navigation
## File tree
```
./client/
components/... <-- See section Components
cssFiles/... <-- Contains some CSS files for the MHTL files at the root of the folder
externalFiles/... <-- Contains some CSS and JS files for external libraries
jsFiles/... <-- Contains the main JS files for the app (except the components)
res/... <-- Contains the images used in the client
```
## Initialization/navigation
For a selected instrument, there is a single HTML file that holds the application : the `SEAWebClient.html` file, which is served as the main route. It includes all the JS files needed, meaning all the JS files located in the `client/jsFiles` folder excepted `SeaWebClientStart.js`, plus the external librairies (`client/externalFiles/`) and the components (`client/components/`).
The entry point is the `SEAWebClientMain.js`, which has a `window.onload` function. First, the grid that holds the different parts (graphics, console...) is computed depending on the screen size. Then, the connexion with the server is initiated with the `buildUpdateConnection` function, located in `SeaWebClientCommunication.js`.
The entry point is the `SEAWebClientMain.js`, which has a `window.onload` function. First, the grid that holds the different parts (graphics, console...) is computed depending on the screen size. Then, the connection with the server is initiated with the `buildUpdateConnection` function, located in `SeaWebClientCommunication.js`.
This function calls the /update route, which will initiate the SSE connexion, retrieving an id, the name of the instrument and the device currently running to the client. The id will be used for all the API calls. When all this information is received, the `loadFirstBlocks()` function is called (`SeaWebClientMain.js`) to populate an array of routes to call, so we can get the content of each block sequentially. Its content is defined by the global variables defined in `SeaWebClientMain.js`, more precisely in the calling cascade of the `treat()` method on the `Settings` function (still in the same file).
This function calls the /update route, which will initiate the SSE connection, retrieving an id, the name of the instrument and the device currently running to the client. The id will be used for all the API calls. When all this information is received, the `loadFirstBlocks()` function is called (`SeaWebClientMain.js`) to populate an array of routes to call, so we can get the content of each block sequentially. Its content is defined by the global variables defined in `SeaWebClientMain.js`, more precisely in the calling cascade of the `treat()` method on the `Settings` function (still in the same file).
The calling cascade is initiated with the `nextInitCommand()` function (`SeaWebClientMain.js`), called just after the `loadFirstBlocks()` function. Every response of each command will be treated in the switch statement of the `successHandler()` function (in `SeaWebClientCommunication.js`). Specifically, the content of each block is dynamically created in JS when the response of the different init commands are received.
### Components
## Components
A component is composed of a JS file and its CSS file. They are grouped in the folder `client/components`. A component is basically a class that inherits from `HTMLELement`, and implement the method connectedCallback, where the HTML of the component has to be defined. Then, it has to be added to the customElements via the line `customElements.define("<component-name>", <ComponentClass>)`. The component's name has to contain dash, otherwise an error is thrown.
The export popup and the dates popup are considered as components just to separate their code from the rest.
The export popup, the dates popup and the curves settings popup are considered as components just to separate their code from the rest.
## Miscellaneous
### About updating graphics
- When the server is pushing data, the newly received data is appened to the current curves (on livemode).
- When zooming in the x direction, when the zoom is complete (for e.g. meaning that there are no longer enough mouse wheel step in a certain range of time), then the resolution is computed, the client asks for the data within the new viewing window with the given resolution, and then sets (overwrites) the data for the curves. This process is done only when zooming out, and we have zoomed in by at least 50% of the previous viewing window
- When zooming in the x direction, when the zoom is complete (for e.g. meaning that there are no longer enough mouse wheel step in a certain range of time), then the resolution is computed, the client asks for the data within the new viewing window with the given resolution, and then sets (overwrites) the data for the curves. This process is done only when zooming out, and we have zoomed in by at least 50% of the previous viewing window.
### About livemode
A user is in livemode when the "now" date is in the viewing window. When the last point gets more recent than the right most value, the viewing window is shrinked, keeping the left mose value.
- A user is in livemode when the "now" date is in the viewing window. When the last point gets more recent than the right most value, the viewing window is shrinked, keeping the left mose value.
- Every plain minute, all the curves are synchronized. For the curve that have not receive any new data, their last known point is retreived at the "now" date.
Every plain minute, all the curves are synchronized. For the curve that have not receive any new data, their last known point is retreived at the "now" date.
### About the user configuration for the graphs
The local storage is used to save the user configuration. The key in an integer, and the value is a stringified JSON object, which looks like the following :
`{"variable":<variable>, "parameter":<parameter> [, "cat":<cat>] [, "color":<color>] [, "unit":<unit>]}`
The indicated optionnal options are saved only if a value was provided for them.
When it is sent to the server, an entry from the local storage is transformed in this way :
`{"<variable>.<parameter>":{["cat":<cat>] [[,] "color":<color>] [[,] "unit":<unit>]}}`
The indicated optionnal options are sent only if a value was provided for them.
### External libraries
## External libraries
| Name | Version | Website |
| -------------------------- | ------- | -------------------------------------- |
| AlertifyJS | v1.8.0 | http://alertifyjs.com |
| ChartJS | v2.9.4 | https://www.chartjs.org |
| \+ Zoom plugin for ChartJS | v0.7.3 | https://www.chartjs.org |
| EventSource | unknown | https://github.com/Yaffle/EventSource/ |
| Hammer.JS | v2.0.7 | http://hammerjs.github.io/ |
| Swipper | v4.5.0 | http://www.idangero.us/swiper/ |
| Name | Version | Website |
| -------------------------- | ------- | -------------------------------------- |
| AlertifyJS | v1.8.0 | http://alertifyjs.com |
| ChartJS | v2.9.4 | https://www.chartjs.org |
| \+ Zoom plugin for ChartJS | v0.7.3 | https://www.chartjs.org |
| EventSource | unknown | https://github.com/Yaffle/EventSource/ |
| Hammer.JS | v2.0.7 | http://hammerjs.github.io/ |
| Swipper | v11.1.12 | https://swiperjs.com |