Merge branch 'immediateChanges' of https://github.com/openwfm/wrfxweb into mergeBranches
[wrfxweb.git] / fdds / js / components / domainSelector.js
blob97d0e21da8455e9f4da873246cbfe71917b42b1a
1 import { controllerEvents, controllers } from './Controller.js';
2 import { daysBetween, IS_MOBILE, localToUTC } from '../util.js';
3 import { simVars } from '../simVars.js';
5 /** Component for the Active Domain selection bar.
6 *
7 * Contents
8 * 1. Initialization block
9 * 2. CreateDomainsForCurrentSimulation block
10 * 3. GetPresets block
11 * 4. DomainSwitch block
14 export class DomainSelector extends HTMLElement {
15 /** ===== Initialization block ===== */
16 constructor() {
17 super();
18 this.innerHTML = `
19 <div id='domain-mobile-wrapper'>
20 <div id='domain-selector-button' class='mobile-button feature-controller hidden'>
21 domains
22 </div>
23 <div id='domain-selector' class='feature-controller hidden'>
24 <div id='domain-selector-label'>Active domain</div>
25 <div id='domain-checkboxes'></div>
26 </div>
27 </div>
31 connectedCallback() {
32 controllers.domainInstance.subscribe(() => {
33 this.createDomainsForCurrentSimulation();
34 });
35 this.initializeDomainSelectorButton();
38 initializeDomainSelectorButton() {
39 const domainButton = this.querySelector('#domain-selector-button');
40 L.DomEvent.disableClickPropagation(domainButton);
41 domainButton.onpointerdown = () => {
42 const domainSelector = this.querySelector('#domain-selector');
43 if (domainSelector.classList.contains('hidden')) {
44 domainSelector.classList.remove('hidden');
45 document.querySelector('.catalog-menu').classList.add('hidden');
46 document.querySelector('#layer-controller-container').classList.add('hidden');
47 } else {
48 domainSelector.classList.add('hidden');
53 /** ===== CreateDomainsForCurrentSimulation block ===== */
54 createDomainsForCurrentSimulation() {
55 this.responsiveUI();
56 simVars.noLevels.clear();
57 let domains = controllers.domainInstance.getValue();
58 controllers.loadingProgress.setValue(0);
60 let presetDomain = this.presetSimValues(domains);
61 this.createDomainCheckboxes(domains, presetDomain);
63 controllers.currentDomain.setValue(presetDomain, controllerEvents.SIM_RESET);
66 createDomainCheckboxes(domains, presetDomain) {
67 const domainCheckboxes = this.querySelector('#domain-checkboxes');
68 domainCheckboxes.innerHTML = '';
69 for(let dom in domains) {
70 let domId = domains[dom];
71 let domainCheckbox = this.createDomainCheckbox(domId, presetDomain);
72 domainCheckboxes.appendChild(domainCheckbox);
76 createDomainCheckbox(dom_id, presetDomain) {
77 let div = document.createElement('div');
78 div.className = 'domain-checkbox';
80 let input = document.createElement('input');
81 input.type = 'radio';
82 input.name = 'domains';
83 input.id = dom_id;
84 if (dom_id == presetDomain) {
85 input.checked = 'yes';
87 input.onclick = () => {
88 this.setUpForDomain(dom_id);
91 let label = document.createElement('label');
92 label.for = dom_id;
93 label.innerText = dom_id;
95 div.appendChild(input);
96 div.appendChild(label);
97 return div;
100 responsiveUI() {
101 if (!IS_MOBILE) {
102 this.querySelector('#domain-selector').classList.remove('hidden');
104 this.querySelector('#domain-selector-button').classList.remove('hidden');
105 document.querySelector('#layers-button').classList.remove('hidden');
108 /** ===== GetPresets block ===== */
109 presetSimValues(domains) {
110 let domId = this.presetDomain(domains);
111 let nextTimestamps = Object.keys(simVars.rasters[domId]).sort();
112 simVars.sortedTimestamps = nextTimestamps;
114 this.presetStartDate(nextTimestamps);
115 this.presetEndDate(nextTimestamps);
116 this.presetCurrentTimestamp(nextTimestamps);
117 this.presetOpacity();
119 return domId;
122 presetDomain(domains) {
123 let domId = domains[0];
124 if (domains.includes(simVars.presets.domain)) {
125 domId = simVars.presets.domain;
127 simVars.presets.domain = null;
128 return domId;
131 presetStartDate(nextTimestamps) {
132 let startDate = nextTimestamps[0];
133 let presetStartDate = localToUTC(simVars.presets.startDate);
134 let desc = simVars.currentDescription;
135 if (nextTimestamps.includes(presetStartDate)) {
136 startDate = presetStartDate;
137 simVars.presets.startDate = null;
138 } else if(desc.indexOf('GACC') >= 0 || desc.indexOf(' FM') >= 0 || desc.indexOf('SAT') >= 0) {
139 let lastTimestamp = nextTimestamps[nextTimestamps.length - 1];
140 for (let i = 2; i <= nextTimestamps.length; i++) {
141 startDate = nextTimestamps[nextTimestamps.length - i];
142 if (daysBetween(startDate, lastTimestamp) >= 15) {
143 startDate = nextTimestamps[nextTimestamps.length - i + 1];
144 break;
148 controllers.startDate.setValue(startDate, controllerEvents.QUIET);
151 presetEndDate(nextTimestamps) {
152 let endDate = nextTimestamps[nextTimestamps.length - 1];
153 let presetEndDate = localToUTC(simVars.presets.endDate);
154 if (nextTimestamps.includes(presetEndDate)) {
155 endDate = presetEndDate;
157 simVars.presets.endDate = null;
158 controllers.endDate.setValue(endDate, controllerEvents.QUIET);
161 presetCurrentTimestamp(nextTimestamps) {
162 let startDate = controllers.startDate.getValue();
163 let endDate = controllers.endDate.getValue();
165 let currentTimestamp = startDate;
166 let presetTimestamp = localToUTC(simVars.presets.timestamp);
167 if (nextTimestamps.includes(presetTimestamp) && presetTimestamp >= startDate && presetTimestamp <= endDate) {
168 currentTimestamp = presetTimestamp;
170 simVars.presets.timestamp = null;
171 controllers.currentTimestamp.setValue(currentTimestamp, controllerEvents.QUIET);
174 presetOpacity() {
175 let opacity = 0.5;
176 let presetOpacity = simVars.presets.opacity;
177 if (presetOpacity && !isNaN(presetOpacity)) {
178 presetOpacity = Number(presetOpacity);
179 if (presetOpacity >= 0 && presetOpacity <= 1) {
180 opacity = presetOpacity;
183 simVars.presets.opacity = null;
184 controllers.opacity.setValue(opacity, controllerEvents.QUIET);
187 /** ===== DomainSwitch block ===== */
188 setUpForDomain(domId) {
189 // set the current domain, must be updated in this order: sortedTimestamps, currentTimestamp, currentDomain
190 let nextTimestamps = Object.keys(simVars.rasters[domId]).sort();
191 let prevTimestamps = simVars.sortedTimestamps;
192 simVars.sortedTimestamps = nextTimestamps;
194 this.updateStartDate(prevTimestamps);
195 this.updateEndDate(prevTimestamps);
196 this.updateCurrentTimestamp(prevTimestamps);
198 controllers.currentDomain.setValue(domId);
201 updateStartDate(prevTimestamps) {
202 let startDate = controllers.startDate.getValue();
203 startDate = this.convertPrevTimestampToCurrentTimestamp(startDate, prevTimestamps);
204 controllers.startDate.setValue(startDate, controllerEvents.QUIET);
207 updateEndDate(prevTimestamps) {
208 let endDate = controllers.endDate.getValue();
209 endDate = this.convertPrevTimestampToCurrentTimestamp(endDate, prevTimestamps);
210 controllers.endDate.setValue(endDate, controllerEvents.QUIET);
213 updateCurrentTimestamp(prevTimestamps) {
214 let currentTimestamp = controllers.currentTimestamp.getValue();
215 currentTimestamp = this.convertPrevTimestampToCurrentTimestamp(currentTimestamp, prevTimestamps);
216 controllers.currentTimestamp.setValue(currentTimestamp, controllerEvents.QUIET);
219 convertPrevTimestampToCurrentTimestamp(prevTimestamp, prevTimestamps) {
220 let nextTimestamps = simVars.sortedTimestamps;
221 if (nextTimestamps.includes(prevTimestamp)) {
222 return prevTimestamp;
224 let prevIndex = prevTimestamps.indexOf(prevTimestamp);
225 let percentage = prevIndex / prevTimestamps.length;
226 let newIndex = Math.floor(nextTimestamps.length * percentage);
228 return nextTimestamps[newIndex];
232 window.customElements.define('domain-selector', DomainSelector);