For Lidar profiles, starts the simulation at the latest timestamp
[wrfxweb.git] / fdds / js / components / domainSelector.js
blobb590c14b480aef952cc741a5af121f0cd82f4d98
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');
107 /** ===== GetPresets block ===== */
108 presetSimValues(domains) {
109 let domId = this.presetDomain(domains);
110 let nextTimestamps = Object.keys(simVars.rasters[domId]).sort();
111 simVars.sortedTimestamps = nextTimestamps;
113 this.presetStartDate(nextTimestamps);
114 this.presetEndDate(nextTimestamps);
115 this.presetCurrentTimestamp(nextTimestamps);
116 this.presetOpacity();
118 return domId;
121 presetDomain(domains) {
122 let domId = domains[0];
123 if (domains.includes(simVars.presets.domain)) {
124 domId = simVars.presets.domain;
126 simVars.presets.domain = null;
127 return domId;
130 presetStartDate(nextTimestamps) {
131 let startDate = nextTimestamps[0];
132 let presetStartDate = localToUTC(simVars.presets.startDate);
133 let desc = simVars.currentDescription;
134 if (nextTimestamps.includes(presetStartDate)) {
135 startDate = presetStartDate;
136 simVars.presets.startDate = null;
137 } else if(desc.indexOf('GACC') >= 0 || desc.indexOf(' FM') >= 0 || desc.indexOf('SAT') >= 0) {
138 let lastTimestamp = nextTimestamps[nextTimestamps.length - 1];
139 for (let i = 2; i <= nextTimestamps.length; i++) {
140 startDate = nextTimestamps[nextTimestamps.length - i];
141 if (daysBetween(startDate, lastTimestamp) >= 8) {
142 startDate = nextTimestamps[nextTimestamps.length - i + 1];
143 break;
147 controllers.startDate.setValue(startDate, controllerEvents.QUIET);
148 controllers.timeSeriesStart.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);
159 controllers.timeSeriesEnd.setValue(endDate, controllerEvents.QUIET);
162 presetCurrentTimestamp(nextTimestamps) {
163 let startDate = controllers.startDate.getValue();
164 let endDate = controllers.endDate.getValue();
165 let currentSim = simVars.currentSimulation;
167 // if currentSim has "lidar" in it, then set the currentTimestamp to the last timestamp
168 let currentTimestamp = currentSim.includes("lidar") ? endDate : startDate;
169 let presetTimestamp = localToUTC(simVars.presets.timestamp);
170 if (nextTimestamps.includes(presetTimestamp) && presetTimestamp >= startDate && presetTimestamp <= endDate) {
171 currentTimestamp = presetTimestamp;
173 simVars.presets.timestamp = null;
174 controllers.currentTimestamp.setValue(currentTimestamp, controllerEvents.QUIET);
177 presetOpacity() {
178 let opacity = 0.5;
179 let presetOpacity = simVars.presets.opacity;
180 if (presetOpacity && !isNaN(presetOpacity)) {
181 presetOpacity = Number(presetOpacity);
182 if (presetOpacity >= 0 && presetOpacity <= 1) {
183 opacity = presetOpacity;
186 simVars.presets.opacity = null;
187 controllers.opacity.setValue(opacity, controllerEvents.QUIET);
190 /** ===== DomainSwitch block ===== */
191 setUpForDomain(domId) {
192 // set the current domain, must be updated in this order: sortedTimestamps, currentTimestamp, currentDomain
193 let nextTimestamps = Object.keys(simVars.rasters[domId]).sort();
194 let prevTimestamps = simVars.sortedTimestamps;
195 simVars.sortedTimestamps = nextTimestamps;
197 this.updateStartDate(prevTimestamps);
198 this.updateEndDate(prevTimestamps);
199 this.updateCurrentTimestamp(prevTimestamps);
201 controllers.currentDomain.setValue(domId);
204 updateStartDate(prevTimestamps) {
205 let startDate = controllers.startDate.getValue();
206 startDate = this.convertPrevTimestampToCurrentTimestamp(startDate, prevTimestamps);
207 controllers.startDate.setValue(startDate, controllerEvents.QUIET);
208 controllers.timeSeriesStart.setValue(startDate);
211 updateEndDate(prevTimestamps) {
212 let endDate = controllers.endDate.getValue();
213 endDate = this.convertPrevTimestampToCurrentTimestamp(endDate, prevTimestamps);
214 controllers.endDate.setValue(endDate, controllerEvents.QUIET);
215 controllers.timeSeriesEnd.setValue(endDate);
218 updateCurrentTimestamp(prevTimestamps) {
219 let currentTimestamp = controllers.currentTimestamp.getValue();
220 currentTimestamp = this.convertPrevTimestampToCurrentTimestamp(currentTimestamp, prevTimestamps);
221 controllers.currentTimestamp.setValue(currentTimestamp, controllerEvents.QUIET);
224 convertPrevTimestampToCurrentTimestamp(prevTimestamp, prevTimestamps) {
225 let nextTimestamps = simVars.sortedTimestamps;
226 if (nextTimestamps.includes(prevTimestamp)) {
227 return prevTimestamp;
229 let prevIndex = prevTimestamps.indexOf(prevTimestamp);
230 let percentage = prevIndex / prevTimestamps.length;
231 let newIndex = Math.floor(nextTimestamps.length * percentage);
233 return nextTimestamps[newIndex];
237 window.customElements.define('domain-selector', DomainSelector);