PageSourceSearch

https://www.drought.gov/modules/custom/general_page_js_css/js/map-helpers/overlay.js?tlrx84

js drought.gov collected 2026-09-24 08:36:05 UTC 9,443 bytes, 263 lines download raw bytes

1/**
2 * This file defines a generalized way to add and remove overlays to elements.
3 * Provides specific functions for handling no data in remote files and spinners
4 * but can also be used in a generalized sense.
5 */
6(function (mapsUtil) {
7  "use strict";
8
9  (function main() {
10    exportConfig();
11  })();
12
13  /**
14   * Draw the missing data message on the map.
15   * @param {Element} elem - A HTML element within the map structure. Generally keyed by .interactive-map.
16   * @param {Metadata} metadata - Metadata for the map.
17   */
18  function addFileNoDataOverlay(elem, metadata) {
19    const map = mapsUtil.findMap(elem);
20    map.append(buildMapOverlayNoData(metadata));
21  }
22
23  /**
24   * Adds the spinner overlay.
25   * @param {Element} elem - A HTML element within the map structure. Generally keyed by .interactive-map.
26   * @param {Metadata} metadata - The maps metadata. Needed for layer key.
27   */
28  function addSpinnerOverlay(elem, metadata) {
29    const map = mapsUtil.findMap(elem);
30    map.activeLayer = metadata.layer; // for clearOverlaySpinnerLoaded
31    const overlay = buildMapOverlaySpinner();
32    map.append(overlay);
33  }
34
35  /**
36   * Clears the missing data overlay.
37   * @param {Element} elem - A HTML element within the map structure. Generally keyed by .interactive-map.
38   */
39  function clearOverlayNoData(elem) {
40    clearOverlayByClassName(elem, ".map-overlay-no-data");
41  }
42
43  /**
44   * Clears the spinner overlay.
45   * @param {Element} elem - A HTML element within the map structure. Generally keyed by .interactive-map.
46   */
47  function clearOverlaySpinner(elem) {
48    clearOverlayByClassName(elem, ".map-overlay-spinner");
49  }
50
51  /**
52   * Clears the spinner overlay, if the main map layer has loaded.
53   * @param {Element} elem - A HTML element within the map structure. Generally keyed by .interactive-map.
54   * @param {Metadata} metadata - The maps metadata. Needed for layer key.
55   */
56  function clearOverlaySpinnerLoaded(elem, metadata) {
57    const map = mapsUtil.findMap(elem);
58    if (map.activeLayer === metadata.layer) {
59      clearOverlaySpinner(elem);
60    }
61  }
62
63  /**
64   * Clears an overlay, if it exists.
65   * @param {Element} elem - A HTML element within the map structure. Generally keyed by .interactive-map.
66   * @param {string} className - Class selector of overlay to remove. Generally map-overlay-spinner or
67   *   map-overlay-no-data.
68   */
69  function clearOverlayByClassName(elem, className) {
70    const map = mapsUtil.findMap(elem);
71    const overlay = map.querySelector(className);
72    if (overlay) {
73      map.removeChild(overlay);
74    }
75  }
76
77  /**
78   * Builds the HTML for an overlay when data is loading.
79   * @return {HTMLDivElement} - The complete HTML element.
80   */
81  function buildMapOverlaySpinner() {
82    const overlay = buildMapOverlay();
83    overlay.classList.add("map-overlay-spinner");
84    const spinner = document.createElement("div");
85    spinner.className = "spinner spinner--centered icon-size--extra-large";
86    overlay.append(spinner);
87    return overlay;
88  }
89
90  /**
91   * Builds the HTML for an overlay when the data is missing.
92   * @param {Metadata} metadata - The metadata for a map. Needed for the missing-text property.
93   * @return {HTMLDivElement} - The complete HTML element.
94   */
95  function buildMapOverlayNoData(metadata) {
96    const overlay = buildMapOverlay();
97    overlay.classList.add("map-overlay-no-data");
98    const text = metadata["missing-text"] || "There is currently no information to display";
99    const innerContent = document.createElement("span");
100    innerContent.style.textShadow = "2px 2px 2px #fff";
101    innerContent.textContent = text;
102    overlay.append(innerContent);
103    return overlay;
104  }
105
106  /**
107   * Builds the generic overlay which content will go into.
108   * @return {HTMLDivElement} - The wrapper HTML element. Extended by other invocations to add text/spinner.
109   */
110  function buildMapOverlay() {
111    const overlay = document.createElement("div");
112    overlay.className = "map-overlay z-100 position-absolute width-full height-full top-0 left-0 display-flex flex-align-center flex-justify-center padding-4 font-body-lg text-bold text-align-center";
113    overlay.style.background = "rgba(216, 216, 216, .3)";
114    return overlay;
115  }
116
117  /**
118   * Entry point to handle remote file having no data for OpenLayers maps
119   *.
120   * Draws overlay on top of map indicating the file has no data in it.
121   * @param {ol.source.Vector} source - Vector source of the main data layer.
122   * @param {Element} elem - Should be used to find the map wrapper for DOM manipulation
123   * @param {Metadata} metadata - Metadata for active tab.
124   */
125  function handleOLSourceNoData(source, elem, metadata) {
126    const url = metadata.layer;
127    if (!url || checkOLSourceForNoData(url, source) === false) {
128      source.set("showNoDataOverlay", false);
129      return;
130    }
131    source.set("showNoDataOverlay", true);
132    addFileNoDataOverlay(elem, metadata);
133  }
134
135  /**
136   * Checks to see if a vector source has any data in it.
137   *
138   * Current known conditions for the file not having data are there being no features, there being exactly 1 feature
139   * with no geometry, on the fire-wx[1|2] layers there being exactly one feature, and on the fireoutlook-day[1|2]
140   * layers there being exactly 2 layers which both have a RISK parameters of -1.
141   * @param {string} url - URL of layer, needed for one-off fire conditions
142   * @param {ol.source.Vector} source - Vector source of the main data layer.
143   * @return {boolean} - true if the missing data overlay should be drawn.
144   */
145  function checkOLSourceForNoData(url, source) {
146    const features = source.getFeatures();
147    if (!features || features.length === 0) {
148      return true;
149    }
150    if (features.length === 1 && !features[0].getGeometry()) {
151      return true;
152    }
153    if (url.includes("firewx-day1") && features.length === 1 && _featureRiskMissing(features[0])) {
154      return true;
155    }
156    if (url.includes("fireoutlook-day") && features.length === 1 && _featureRiskMissing(features[0])) {
157      return true;
158    }
159    return (
160      url.includes("fireoutlook-day") &&
161      features.length === 2 &&
162      _featureRiskMissing(features[0]) &&
163      _featureRiskMissing(features[1])
164    );
165  }
166
167  /**
168   * Entry point to handle remote file having no data. Currently only w
168orks for geojson/json files.
169   * Draws overlay on top of map indicating the file has no data in it.
170   *
171   * @param {Element} elem - Should be used to find the map wrapper for DOM manipulation
172   * @param {Metadata} metadata Metadata for active tab.
173   * @param {{}} data - Pre-fetched data of layer. Either topojson or geojson.
174   */
175  function handleFileNoData(elem, metadata, data) {
176    const url = metadata.layer;
177    if (!url) {
178      return;
179    }
180    if (mapsUtil.getExtension(url) !== "json" && mapsUtil.getExtension(url) !== "geojson") {
181      return;
182    }
183    if (checkJsonForNoData(url, data) === false) {
184      return;
185    }
186    addFileNoDataOverlay(elem, metadata);
187  }
188
189  /**
190   * Checks to see if a geojson or json file has any data in it. Current known conditions for the file not having data
191   * are there being no features, there being exactly 1 feature with no geometry, on the fire-wx[1|2] layers there
192   * being exactly one feature, and on the on the fireoutlook-day[1|2] layers there being exactly 2 layers which both
193   * have a RISK parameters of -1.
194   *
195   * @param {string} url - URL of layer, needed for one off fire conditions
196   * @param {{}} data - GeoJSON of layer.
197   * @return {boolean} - true if the file is missing and geometry.
198   */
199  function checkJsonForNoData(url, data) {
200    if (!data) {
201      return true;
202    }
203    const features = data.features;
204    if (!features || features.length === 0) {
205      return true;
206    }
207    if (features.length === 1 && !features[0].geometry) {
208      return true;
209    }
210    if (url.indexOf("firewx-day1") !== -1 && features.length === 1 && _featureRiskMissing(features[0])) {
211      return true;
212    }
213    if (url.indexOf("fireoutlook-day") !== -1 && features.length === 1 && _featureRiskMissing(features[0])) {
214      return true;
215    }
216    if (
217      url.includes("fireoutlook-day") &&
218      features.length === 2 &&
219      _featureRiskMissing(features[0]) &&
220      _featureRiskMissing(features[1])
221    ) {
222      return true;
223    }
224    return false;
225  }
226
227  /**
228   * Checks if a feature on a fire wx/outlook layer has a RISK value which indicates there's no data.
229   *
230   * Handles both openlayers features and text parsed from topojson for d3.
231   * @param {ol.Feature|{}} feature - Feature to check.
232   * @return {boolean} - true if the map should render the missing data overlay.
233   */
234  function _featureRiskMissing(feature) {
235    if (feature.get && typeof feature.get === "function" && feature.get("RISK") === "-1") {
236      return true;
237    }
238    return (
239      feature.hasOwnProperty("properties") &&
240      feature.properties.hasOwnProperty("RISK") &&
241      feature.properties.RISK === "-1"
242    );
243  }
244
245  /**
246   * Exports functions to window.overlay.
247   */
248  function exportConfig() {
249    window.overlay = {
250      addFileNoDataOverlay,
251      clearOverlayNoData,
252      clearOverlaySpinner,
253      clearOverlaySpinnerLoaded,
254      clearOverlayByClassName,
255      buildMapOverlaySpinner,
256      buildMapOverlayNoData,
257      buildMapOverlay,
258      addSpinnerOverlay,
259      handleFileNoData,
260      handleOLSourceNoData,
261    };
262  }
263})(window.mapsUtil);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.