From b70ea6c8341e675e955fa1bf5a9f6a2a35fc080f Mon Sep 17 00:00:00 2001 From: Elliott Rose Date: Tue, 14 Mar 2023 12:39:24 +0100 Subject: [PATCH 1/3] Add various style improvements. Set up style bar and info pane for forecast mosiac to resize and tilt colorbar values for better readability. --- assets/custom-functions.js | 76 +++++++++++++++++++++++++++++------- assets/sidebar.css | 14 +++---- assets/style.css | 56 +++++++++++++++++++++++--- data_handler.py | 2 + tabs/evaluation_callbacks.py | 22 ++++++++--- 5 files changed, 137 insertions(+), 33 deletions(-) diff --git a/assets/custom-functions.js b/assets/custom-functions.js index e8ba802..f0e1271 100644 --- a/assets/custom-functions.js +++ b/assets/custom-functions.js @@ -137,7 +137,11 @@ $(window).on('load', function removeFullscreen () { $(document).ready(function () { $(document).on('click', ".SingleDatePickerInput_clearDate, .SingleDatePicker", function moveDatePicker () { const element = document.getElementsByClassName('DayPicker')[0]; - if (element != null) { + //we still want the menu to go below on eval/vis for modis + const evalVis = document.getElementById('eval-date'); + if (evalVis != null) { + return + }else if (element != null) { element.style.position = 'absolute'; element.style.bottom = '78px'; }else { @@ -189,13 +193,16 @@ $(document).ready(function () { }); }); + //================== Stats table carets =============================================== // The aeronet stats table changes the position/index of the regions when they // are clicked, so we cannot easily assign a class to the regions that will maintain on click, // so we must remove the carets on click, and then add them back after the table has finished + // changing it's state + // ADD FUNCTION TO WAIT FOR TABLE TO FINISH CHANGING -function waitForMutation(selector) { +function waitForMutation(selector, func) { return new Promise(resolve => { if (document.querySelector(selector)) { return resolve(document.querySelector(selector)); @@ -203,17 +210,8 @@ function waitForMutation(selector) { const observer = new MutationObserver(mutations => { if (document.querySelector(selector)) { resolve(document.querySelector(selector)); - //Carets will populate in the wrong rows after click, so we must remove them - for (const element of mutations) { - if (['Mediterranean','NAfrica', 'MiddleEast'].includes(element.oldValue)) { - //GET ELEMENTS PARENT NODE 2 ABOVE AS IT CONTAINS THE TARGET CLASS - const target = element.target.parentNode.parentNode; - target.classList.remove('table_caret_up'); - target.classList.remove('table_caret_down'); - }; - } - // Now add the carets back in where appropriate - flipCarets(); + console.log(selector); + func(mutations); } }); observer.observe(document.body, { @@ -225,6 +223,21 @@ function waitForMutation(selector) { }); } +//FIND THE REGIONS TO REMOVE THE CARETS BEFORE FLIPPING THEM +function targetRegions(mutations) { + //Carets will populate in the wrong rows after click, so we must remove them + for (const element of mutations) { + if (['Mediterranean','NAfrica', 'MiddleEast'].includes(element.oldValue)) { + //GET ELEMENTS PARENT NODE 2 ABOVE AS IT CONTAINS THE TARGET CLASS + const target = element.target.parentNode.parentNode; + target.classList.remove('table_caret_up'); + target.classList.remove('table_caret_down'); + }; + } + // Now add the carets back in where appropriate + flipCarets(); +} + //CREATE FUNCTION TO FIND REGIONS AND FLIP CARETS AS NEEDED function flipCarets() { var areas = "td:contains('Europe'), td:contains('Mediterranean'),td:contains('NAfrica'),td:contains('MiddleEast')"; @@ -256,7 +269,42 @@ function flipCarets() { //ADD FUNCTION TO WAIT FOR CLICKS ON AREAS THAT SHOULD TRIGGER CARET FLIPS $(document).ready(function () { $(document).on('click', "td:contains('Europe'), td:contains('Mediterranean'),td:contains('NAfrica'),td:contains('MiddleEast'), #scores-apply, #evaluation-tab", function () { - waitForMutation('td.dash-cell.column-0'); + waitForMutation('td.dash-cell.column-0', targetRegions); }) }) //================== Stats table carets END =============================================== + +//==================Functions to flip adjust colorbar values for only concentration var ==================== +//GET THE VARIABLE VALUE +// function getVars() { +// curvar = document.querySelector('.Select-value-label').innerHTML; +// curvar = curvar.split(' ').join('_') +// return curvar; +// } +// +// function tiltValues() { +// console.log('curvar', getVars()); +// if (getVars() == 'Concentration') { +// // Get all the elements with class name 'leaflet-control-colorbar' +// const containers = document.querySelectorAll('.leaflet-control-colorbar'); +// // Loop through each container element +// containers.forEach(container => { +// // Get the second div inside the container +// const secondDiv = container.querySelectorAll('div')[1]; +// // Get all the spans inside the second div +// const spans = secondDiv.querySelectorAll('span'); +// // Rotate each span element by 30 degrees +// spans.forEach(span => { +// span.style.transform = 'rotate(30deg)'; +// }); +// }); +// }; +// }; +// +// $(document).ready(function () { +// $(document).on('click', "#models-apply", function () { +// console.log('running'); +// setTimeout(tiltValues, 300); +// }) +// }) +//==================END Functions to flip adjust colorbar values for only concentration var ==================== diff --git a/assets/sidebar.css b/assets/sidebar.css index 8fb5d1c..a19a2ef 100644 --- a/assets/sidebar.css +++ b/assets/sidebar.css @@ -94,11 +94,9 @@ overflow: hidden; } -/* -.sidebar-first-item .Select-menu-outer .ReactVirtualized__Grid.ReactVirtualized__List.VirtualSelectGrid { - height: 100% !important; +#variable-dropdown-forecast div.Select.is-open { + height: auto; } -*/ .sidebar-dropdown { max-height: 46vh; @@ -121,8 +119,8 @@ /* Custom control: Classes recently added by Francesco */ .custom-control { - padding-left: 0; - padding-right: 0; + padding-left: 0; + padding-right: 0; } .custom-control-label { @@ -222,7 +220,7 @@ /* background-image: url("/daily_dashboard/assets/images/Icon_Info.png"); */ background-position: center; width: 52px !important; - height: 5vh; + height: 48px; background-color: var(--dark_grey); border-right: 4px solid #4f4f4f !important; } @@ -239,7 +237,7 @@ background-position: 10% 55%; background-color: var(--dark_grey); width: 100%; - height: 5vh; + height: 48px; color: white; padding-top: 0.6rem; } diff --git a/assets/style.css b/assets/style.css index 819c318..2aa7525 100644 --- a/assets/style.css +++ b/assets/style.css @@ -93,14 +93,14 @@ a.modebar-btn { #graph-eval-aeronet { padding: 0; margin: 0; - height: 69vh !important; + height: 83vh !important; overflow: hidden; } #graph-eval-modis-obs, #graph-eval-modis-mod { padding: 0; margin: 0; - height: 67vh !important; + height: 80vh !important; overflow: hidden; } @@ -150,10 +150,32 @@ a.modebar-btn { margin-right: 1rem; } +#eval-graph .disclaimer { + display: flex; + justify-content: flex-start; + bottom: 1px; +} + +#eval-vis-modis-disclaimer{ + justify-content: flex-end !important; +} + +#graph-eval-aeronet .disclaimer { + display: flex; + justify-content: flex-end !important; + bottom: 1px; + margin-right: 16px; +} + .layout-dropdown .disclaimer>p { margin: .3rem 0rem; } +#scores-map-modal .disclaimer { + display: block; + position: initial; +} + .btn-link { color: var(--blue); font-family: "Roboto", sans-serif !important; @@ -251,7 +273,7 @@ div.SingleDatePickerInput { width: 34px; height: 34px; outline: none !important; - margin-top: 2px; + margin-top: 1px; margin-right: 5px; } @@ -345,6 +367,7 @@ div.SingleDatePickerInput { width: 34px; height: 34px; margin-right: 0.5rem; + margin-top: 3px; border: none !important; outline: none !important; color: var(--blue); @@ -402,6 +425,10 @@ div.SingleDatePickerInput { display: block !important; } +#eval-date-picker .SingleDatePickerInput { + background-color: white !important; +} + .linetool .dropdown>button { width: 9.5rem; text-align: left; @@ -416,6 +443,14 @@ div.SingleDatePickerInput { padding-left: 1rem; } +.statistics-inputs .dropdown-menu.show { + padding-right: 0.4rem !important; +} + +#obs-models-dropdown { + padding-right: .7rem; +} + .linetool .DateInput { height: 36px; line-height: 36px !important; @@ -453,6 +488,7 @@ div.SingleDatePickerInput { } .navbar-timebar { + height: 48px; display: flex; flex-direction: row; justify-content: flex-start; @@ -511,7 +547,7 @@ div.SingleDatePickerInput { height: 100%; background-color: var(--blue); border-right: 1px solid var(--dark_grey); - height: 5vh; + height: 48px; } .timeslider { @@ -641,7 +677,7 @@ div.dropdown-menu.show { margin-bottom: 0; overflow: hidden; text-overflow: ellipsis; - font-size: 0.8vw; + font-size: 0.8rem; } .popup-map-point { @@ -770,6 +806,16 @@ div.dropdown-menu.show { .leaflet-control-colorbar { top: 42px !important; font-size: .8em !important; + +} + +#prob-graph .leaflet-control-colorbar.leaflet-control { + top: 122px !important; + position: fixed; +} + +.leaflet-control-colorbar div:nth-child(2) span { + transform: rotate(20deg) !important; } .leaflet-control-zoom-fullscreen { diff --git a/data_handler.py b/data_handler.py index d48a43a..e9ff145 100644 --- a/data_handler.py +++ b/data_handler.py @@ -1065,6 +1065,8 @@ class FigureHandler(object): zoom = 3.5 -(aspect[0]-aspect[0]*0.4) if colorbar is not None: colorbar.width = 320 - 30 * aspect[0] + if aspect == (3,4): + colorbar.width = 320 - 38 * aspect[0] colorbar.height = 8 if DEBUG: print("ZOOM", zoom) if DEBUG: print("CENTER", center) diff --git a/tabs/evaluation_callbacks.py b/tabs/evaluation_callbacks.py index 80cc470..1990d70 100644 --- a/tabs/evaluation_callbacks.py +++ b/tabs/evaluation_callbacks.py @@ -701,9 +701,14 @@ def update_eval_aeronet(n_clicks, sdate, edate, obs): edate = end_date stations, points_layer = get_obs1d(sdate, edate, obs, DEFAULT_VAR) - fig = get_figure(model=None, var=DEFAULT_VAR, layer=points_layer) - # if DEBUG: print("---", fig) - return stations.to_dict(), fig + eval_graph = html.Div([ + get_figure(model=None, var=DEFAULT_VAR, layer=points_layer), + html.Div(DISCLAIMER_OBS, + className='disclaimer') + ], + id='graph-eval-aeronet', + ) + return stations.to_dict(), eval_graph @dash.callback( @@ -788,9 +793,12 @@ def update_eval(obs): updatemode='bothdates', )] - eval_graph = html.Div( + eval_graph = html.Div([ get_figure(), - id='graph-eval-aeronet', + html.Div(DISCLAIMER_OBS, + className='disclaimer') + ], + id='graph-eval-aeronet', ) # eval_graph = [dbc.Spinner( # get_graph( @@ -837,7 +845,9 @@ def update_eval(obs): id='graph-eval-modis-mod', ), html.Div(DISCLAIMER_NO_FORECAST, - className='disclaimer') + className='disclaimer', + id='eval-vis-modis-disclaimer' + ) ], ) eval_graph = [dbc.Row([ -- GitLab From d9854a483099d3bd8f89a09ea784e5ab1c316bb8 Mon Sep 17 00:00:00 2001 From: Elliott Rose Date: Thu, 16 Mar 2023 11:36:44 +0100 Subject: [PATCH 2/3] Add tilt functionality to colorbar values for Concentration variable. Add colorbar sizing to match info bar. --- assets/custom-functions.js | 99 +++++++++++++++++++++++++------------- assets/style.css | 8 +-- data_handler.py | 7 ++- 3 files changed, 75 insertions(+), 39 deletions(-) diff --git a/assets/custom-functions.js b/assets/custom-functions.js index f0e1271..2f71e9c 100644 --- a/assets/custom-functions.js +++ b/assets/custom-functions.js @@ -210,7 +210,7 @@ function waitForMutation(selector, func) { const observer = new MutationObserver(mutations => { if (document.querySelector(selector)) { resolve(document.querySelector(selector)); - console.log(selector); + // console.log(mutations); func(mutations); } }); @@ -274,37 +274,70 @@ $(document).ready(function () { }) //================== Stats table carets END =============================================== -//==================Functions to flip adjust colorbar values for only concentration var ==================== + +//==================Functions to flip adjust colorbar values for only concentration var === //GET THE VARIABLE VALUE -// function getVars() { -// curvar = document.querySelector('.Select-value-label').innerHTML; -// curvar = curvar.split(' ').join('_') -// return curvar; +function getVars() { + const search = window.location.search + const urlParams = new URLSearchParams(search); + const currentVar = urlParams.get('var'); + return currentVar; +} + +function tiltValues() { + if (getVars() == 'concentration') { + const containers = document.querySelectorAll('.leaflet-control-colorbar'); + containers.forEach(container => { + const secondDiv = container.querySelectorAll('div')[1]; + const spans = secondDiv.querySelectorAll('span'); + spans.forEach(span => { + span.style.transform = 'rotate(30deg)'; + span.style.paddingTop = '2px'; + }); + }); + }; +}; + +function setWidthForColorbars(nothing) { + const colorbars = document.querySelectorAll('.leaflet-control-colorbar'); + colorbars.forEach(colorbar => { + const info = document.querySelector('.info').offsetWidth; + colorbar.style.maxWidth = info.toString() + 'px'; + }); +} + +// ADD FUNCTION TO WAIT FOR TABLE TO FINISH CHANGING +// function wait(selector, func) { +// return new Promise(resolve => { +// if (document.querySelector(selector)) { +// return resolve(document.querySelector(selector)); +// }; +// const observer = new MutationObserver(mutations => { +// if (document.querySelector(selector)) { +// resolve(document.querySelector(selector)); +// console.log(mutations); +// func(mutations); +// } +// }); +// observer.observe(document.body, { +// childList: true, +// subtree: true, +// attributes: true, +// }); +// }); // } -// -// function tiltValues() { -// console.log('curvar', getVars()); -// if (getVars() == 'Concentration') { -// // Get all the elements with class name 'leaflet-control-colorbar' -// const containers = document.querySelectorAll('.leaflet-control-colorbar'); -// // Loop through each container element -// containers.forEach(container => { -// // Get the second div inside the container -// const secondDiv = container.querySelectorAll('div')[1]; -// // Get all the spans inside the second div -// const spans = secondDiv.querySelectorAll('span'); -// // Rotate each span element by 30 degrees -// spans.forEach(span => { -// span.style.transform = 'rotate(30deg)'; -// }); -// }); -// }; -// }; -// -// $(document).ready(function () { -// $(document).on('click', "#models-apply", function () { -// console.log('running'); -// setTimeout(tiltValues, 300); -// }) -// }) -//==================END Functions to flip adjust colorbar values for only concentration var ==================== + +$(document).ready(function () { + $(document).on('click', "#models-apply, .DayPicker, .SingleDatePickerInput_clearDate", function () { + // wait('#graph-collection', tiltValues); + setTimeout(tiltValues, 500); + setTimeout(setWidthForColorbars, 500); + }) +}) + +$(document).ready(function () { + setTimeout(tiltValues, 1500); + setTimeout(setWidthForColorbars, 1500); +}); +//==================END Funcfions to flip adjust colorbar values for only concentration var ========== + diff --git a/assets/style.css b/assets/style.css index 2aa7525..0368bc0 100644 --- a/assets/style.css +++ b/assets/style.css @@ -814,10 +814,10 @@ div.dropdown-menu.show { position: fixed; } -.leaflet-control-colorbar div:nth-child(2) span { - transform: rotate(20deg) !important; -} - +/* .leaflet-control-colorbar div:nth-child(2) span { */ +/* transform: rotate(20deg) !important; */ +/* } */ +/**/ .leaflet-control-zoom-fullscreen { display: none !important; } diff --git a/data_handler.py b/data_handler.py index e9ff145..c871ff9 100644 --- a/data_handler.py +++ b/data_handler.py @@ -232,7 +232,7 @@ INFO_STYLE = { "zIndex": "1000", "fontFamily": '"Roboto", sans-serif', "fontSize": "14px", - "fontWeight": "bold" + "fontWeight": "bold", } DISCLAIMER_NO_FORECAST = [html.Span(html.P("""Dust data ©2023 WMO Barcelona Dust Regional Center."""), id='forecast-disclaimer')] @@ -1064,7 +1064,8 @@ class FigureHandler(object): if zoom is None: zoom = 3.5 -(aspect[0]-aspect[0]*0.4) if colorbar is not None: - colorbar.width = 320 - 30 * aspect[0] + colorbar.width = 320 - 15 * aspect[0] + colorbar.style = {'overflow':'hidden', 'white-space':'nowrap'} if aspect == (3,4): colorbar.width = 320 - 38 * aspect[0] colorbar.height = 8 @@ -1092,6 +1093,8 @@ class FigureHandler(object): )) if self.model is not None: CUR_INFO_STYLE = INFO_STYLE.copy() + if colorbar is not None: + CUR_INFO_STYLE['width'] = str(colorbar.width) + "px" if aspect[0] > 2: CUR_INFO_STYLE['fontSize'] = "{}px".format(int(INFO_STYLE['fontSize'][:-2])-aspect[0]+ 0.3) info = html.Div( -- GitLab From b5f1a08074ec9a65e64db1ccd86ef20270039b73 Mon Sep 17 00:00:00 2001 From: Elliott Rose Date: Thu, 16 Mar 2023 15:12:54 +0100 Subject: [PATCH 3/3] Fix bug with variable menu overflow after eval/stats map use. Fix 0 rc-slider value being grey when the last value is selected --- .gitignore | 1 + assets/custom-functions.js | 36 ------------------------------------ assets/sidebar.css | 13 ++++--------- assets/style.css | 8 ++++++++ 4 files changed, 13 insertions(+), 45 deletions(-) diff --git a/.gitignore b/.gitignore index b831a6a..d36a28c 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ log *.swp *.swo /js/tmp/ +/conf/was_dev_erose.json diff --git a/assets/custom-functions.js b/assets/custom-functions.js index 2f71e9c..e7937dc 100644 --- a/assets/custom-functions.js +++ b/assets/custom-functions.js @@ -75,20 +75,6 @@ $(document).ready(function () { }); }); -// Remove yellow from rc-slider-mark-text when moved -$(document).ready(function () { - $(document).on('click','.rc-slider' , function () { - const handle = document.getElementsByClassName('rc-slider-handle')[0]; - const text = document.getElementsByClassName('rc-slider-mark-text')[0]; - if (handle.style.left == '100%'){ - text.style.color = '#999'; - }else{ - text.style.color = '#F1B545'; - } - }) -}) - - // Add logos for the animated gifs $(document).ready(function () { $(document).on('click', "#slider-graph", function () { @@ -306,30 +292,8 @@ function setWidthForColorbars(nothing) { }); } -// ADD FUNCTION TO WAIT FOR TABLE TO FINISH CHANGING -// function wait(selector, func) { -// return new Promise(resolve => { -// if (document.querySelector(selector)) { -// return resolve(document.querySelector(selector)); -// }; -// const observer = new MutationObserver(mutations => { -// if (document.querySelector(selector)) { -// resolve(document.querySelector(selector)); -// console.log(mutations); -// func(mutations); -// } -// }); -// observer.observe(document.body, { -// childList: true, -// subtree: true, -// attributes: true, -// }); -// }); -// } - $(document).ready(function () { $(document).on('click', "#models-apply, .DayPicker, .SingleDatePickerInput_clearDate", function () { - // wait('#graph-collection', tiltValues); setTimeout(tiltValues, 500); setTimeout(setWidthForColorbars, 500); }) diff --git a/assets/sidebar.css b/assets/sidebar.css index a19a2ef..bfdaba5 100644 --- a/assets/sidebar.css +++ b/assets/sidebar.css @@ -61,13 +61,12 @@ .sidebar .card-header { padding-left: .5rem; - padding-right: 0px; + padding-right: 0px; } .sidebar-item { height: 2rem; margin: 1rem 0; - /*border-bottom: 1px solid lightgrey;*/ } .sidebar-item>label { @@ -89,13 +88,9 @@ color: var(--blue); } -.sidebar-first-item .Select-menu-outer { +#variable-dropdown-forecast div.Select-menu-outer .Select-menu { + height: auto !important; background-color: var(--yellow) !important; - overflow: hidden; -} - -#variable-dropdown-forecast div.Select.is-open { - height: auto; } .sidebar-dropdown { @@ -261,7 +256,7 @@ span>#was-apply { margin: 0.5rem 0; } -.sidebar-bottom .btn { +.sidebar-bottom .btn { border-radius: 0; background-repeat: no-repeat; height: 10px; diff --git a/assets/style.css b/assets/style.css index 0368bc0..40da326 100644 --- a/assets/style.css +++ b/assets/style.css @@ -919,6 +919,14 @@ div.dropdown-menu.show { right: 5px; } +#prob-graph .leaflet-interactive, #was-graph .leaflet-interactive , #graph-eval-modis-mod .leaflet-interactive, #obs-vis-graph .leaflet-interactive { + cursor: pointer !important; +} + +#prob-graph .leaflet-interactive:active, #was-graph .leaflet-interactive:active , #graph-eval-modis-mod .leaflet-interactive:active , #obs-vis-graph .leaflet-interactive:active { + cursor: grabbing !important; +} + .leaflet-interactive { cursor: crosshair !important; } -- GitLab