diff --git a/src/AdvancedWeatherView.vue b/src/AdvancedWeatherView.vue index a8abeeaf..d1c56ac4 100644 --- a/src/AdvancedWeatherView.vue +++ b/src/AdvancedWeatherView.vue @@ -3,10 +3,11 @@ - -

Just how cloudy is it in {{ locationName }} in April? + +

Just how cloudy is it in {{ locationName }} in April? ' >

- - - - - - - + + + + + + + + + - - - - - - + + + {{ displayData ? (needToUpdate ? 'Update Map' : 'Shown on Map') : 'Show on Map' }} + @click="updateData()" + > + {{ displayData ? (needToUpdate ? 'Update Map' : 'Shown on Map') : 'Show on Map' }} + + - - - + + - +
-

Show cloud cover statistics for currently selected location: {{ locationName }}

+

Show cloud cover statistics for currently selected location: {{ locationName }}

Show details -
- - + +
-
+
-

Cloud Cover for {{ locationName }} for {{ mapSubsets.get(dataSubset) }}:

+

Cloud Cover for {{ mapSubsets.get(dataSubset) }}:

Cloud Cover for {{ locationName }}:

Location not in bounds
- - - - + + +
- {{ mapDescriptionText }} + {{ mapDescriptionText }} +
-
- + + - + + :y-axis-options="{ + ticks: {callback: (value: number, index: number) => { + if (value < 0 || value > 1) {return;} + return (value * 100).toFixed(0) + '%'; + }}}" + timeseries + color="#aaa" + show-scatter + :annotations="[...skyCoverCodeRanges.map(([_,[min,max]],i) => { + return { + type: 'box', + yMin: min/100, + yMax: max/100, + backgroundColor: colorMap[i], + drawTime: 'beforeDraw', + borderColor: colorMap[i] + } + }), + ...skyCoverCodeRanges.map(([label,[min,max]],i) => { + return { + type: 'line', + borderWidth: 0, + drawTime: 'beforeDatasetsDraw', + + label: { + display: true, + color: 'black', + backgroundColor: 'transparent', + content: skyCoverCodes[i], + }, + xMin: new Date(2023, 0, 8), + yMin: (min + max) / 200, + yMax: (min + max) / 200, + }; + }) + ]" + /> - Close + Close @@ -427,7 +436,25 @@ export default defineComponent({ type: Object as PropType | undefined, default: cityBoston, required: true, - } + }, + + showOnMap: { + type: Boolean, + default: false, + required: false, + }, + + showCharts: { + type: Boolean, + default: false, + required: false, + }, + + fullscreen: { + type: Boolean, + default: false, + required: false, + }, }, data() { @@ -449,7 +476,7 @@ export default defineComponent({ 2018, 2019, 2020, 2021, 2023 ], elNinoYears: [2003, 2007, 2010, 2016], - laNinaYears: [2000, 2008, 2011, 2012, 2021, 2022], + laNinaYears: [2000, 2008, 2011, 2012, 2021, 2022, 2023], neutralYears: [2001, 2002, 2004, 2005, 2006, 2009, 2013, 2014, 2015, 2017, 2018], selectedYear: 2021, selectedStat: 'median' as Statistics, @@ -506,9 +533,10 @@ export default defineComponent({ locationName: '', inBounds: false, displayData: false, - displayCharts: false, + displayCharts: this.showCharts, showCloudCover: true, transferFunction: this.transferFunction8, + loadingNewMap: false, }; }, @@ -525,7 +553,7 @@ export default defineComponent({ this.loadEightDayData().then(() => { console.log('preloading data'); this.dataloaded = true; - this.updateData(false); + this.updateData(this.showOnMap); this.updateMapDescriptionText(); }); } @@ -555,7 +583,7 @@ export default defineComponent({ subsetSelected() { // return !this.allYears.every(y => this.selectedYears.includes(y)); - return (this.selectedYears.length < this.allYears.length); + return (this.selectedYears.length < this.allYears.length) || this.selectedStat === 'singleyear'; }, hideHistogramSubset() { @@ -601,7 +629,7 @@ export default defineComponent({ // show the lat lon of index this.allYears.map((year) => { - allData.push({'x': new Date(year, 4, 8), 'y':this.allCloudData[year][index].cloudCover}); + allData.push({'x': new Date(year, 3, 8), 'y':this.allCloudData[year][index].cloudCover}); }); // console.log('index', index, this.latitudes[index], this.longitudes[index], allData.map(d => d.y)); return allData; @@ -655,7 +683,7 @@ export default defineComponent({ if (index === -1 || index === null) { return; } - allData.push({'x':new Date(year, 4, 8), 'y':data[index].cloudCover}); + allData.push({'x':new Date(year, 3, 8), 'y':data[index].cloudCover}); }); return allData; @@ -671,7 +699,6 @@ export default defineComponent({ locationValue(): number | null { - console.log('locationValue'); if (!this.inBounds) {return null;} if (this.selectedStat === 'mean') { @@ -756,8 +783,8 @@ export default defineComponent({ } return [{ type: 'scatter', - label: this.mapSubsets.get(this.dataSubset) as string, - backgroundColor: data.map(_v => 'goldenrod'), + label: this.selectedStat !== 'singleyear' ? this.mapSubsets.get(this.dataSubset) as string : `${this.selectedYear}`, + backgroundColor: data.map(_v => '#eac402'), data: data, pointRadius: 6, borderColor: 'black', @@ -1006,9 +1033,10 @@ export default defineComponent({ this.displayData = display; if (display){ this.needToUpdate = false; + this.loadingNewMap = true; } this.updateMapDescriptionText(); - + if (this.modisDataSet === '1day') { this.transferFunction = this.transferFunction1; } @@ -1131,7 +1159,8 @@ export default defineComponent({ // Displaying {{ selectedStat === 'singleyear' ? '' : statText.get(selectedStat)?.toLowerCase() }} cloud cover for {{ selectedStat === 'singleyear' ? selectedYear : mapSubsets.get(dataSubset) }}. const stat = this.selectedStat === 'singleyear' ? '' : this.statText.get(this.selectedStat); const subset = this.selectedStat === 'singleyear' ? this.selectedYear : this.mapSubsets.get(this.dataSubset); - this.mapDescriptionText = `Displaying ${stat} cloud cover for ${subset}.`; + const modis = this.modisDataSet === '1day' ? '1-day' : '8-day'; + this.mapDescriptionText = `Displaying ${modis} ${stat} cloud cover for ${subset}.`; }, getCloudCoverText(val: number | null): [number | null, string | undefined] { @@ -1155,7 +1184,7 @@ export default defineComponent({ watch: { modelValue(value: boolean) { - if (value) { + if (value && Object.keys(this.allModisData['8day']).length === 0) { console.log('loading data'); this.loadEightDayData().then(() => { console.log('finished loading data'); @@ -1164,6 +1193,7 @@ export default defineComponent({ }); } else { console.log('closing AWV view'); + this.needToUpdate = true; // this.displayData = false; } }, @@ -1219,7 +1249,13 @@ export default defineComponent({ #advanced-weather-view { --color: #eac402; + --default-font-size: clamp(10px, min(1.7vh, 1.7vw), 1.1rem); font-size: var(--default-font-size); + --smaller-font: calc(1 * var(--default-font-size)); + + h1 { + font-size: 1.5em; + } p.intro { font-size: 1em; @@ -1227,13 +1263,9 @@ export default defineComponent({ strong.attention { font-weight: bold; - font-size: 1em; color: var(--color); } - #chart-intro { - - } canvas.chartjs { border-radius: 5px; @@ -1241,6 +1273,18 @@ export default defineComponent({ .graph-col { height: 300px; + padding: 6px; + } + + .v-btn { + font-size: var(--smaller-font); + } + + .modis-radio { + margin-top: 0.125em; + } + .v-label { + font-size: var(--smaller-font); } #awv-map-description { @@ -1251,24 +1295,60 @@ export default defineComponent({ .map-colorbar { display: flex; + max-width: 99%; } - .map-container { - contain: strict; - aspect-ratio: 2; + #awv-map { + &.show-after .map-container::after { + content: " "; + + display:flex; + width: 100%; + min-height: 2.5em; + height: max-content; + align-items: center; + justify-content: center; + font-size: calc(1 * var(--default-font-size)); + + position: absolute; + top: 0; + left: 0; + + color: black; + background-color: #cccccc77; + z-index: 500; + + backdrop-filter: blur(5px) saturate(50%); + } + + &.show-after.need-to-update .map-container::after { + content: "Press 'Update Map' to view new selection"; + } + + &.show-after.no-data-shown .map-container::after { + content: "Press 'Show on Map' to view data"; + } + + } - .force-vuetify-small-font { - font-size: 0.8em!important; + .map-container { + contain: strict; + aspect-ratio: 1.5; + max-height: 350px; } .sentence-query { font-weight: bold; font-size: 1.125em; + @media (max-width: 600px) { + font-size: 1.25em; + } + - > * { - margin: 0.25em auto; + >label, >select { + margin: 0.25em 0.5ch; } > label { @@ -1296,6 +1376,13 @@ export default defineComponent({ margin-left: 1rem; margin-bottom: 1rem; font-size: 1em; + + @media (max-width: 810px) { + .label-icon-value-text-container { + width: max-content; + } + } + } .bold .label-icon-value-text-label { @@ -1303,7 +1390,6 @@ export default defineComponent({ font-size: 1.12em; } - + } - -./utils \ No newline at end of file + \ No newline at end of file diff --git a/src/BarChart.vue b/src/BarChart.vue index 4dac8fdf..38bb5d76 100644 --- a/src/BarChart.vue +++ b/src/BarChart.vue @@ -157,7 +157,13 @@ export default defineComponent({ type: Boolean, default: false, required: false - } + }, + + showLegend: { + type: Boolean, + default: false, + required: false + }, }, @@ -232,7 +238,7 @@ export default defineComponent({ }, // https://www.chartjs.org/docs/latest/configuration/legend.html legend: { - display: true + display: this.showLegend, }, tooltip: { diff --git a/src/CloudDataExplainer.vue b/src/CloudDataExplainer.vue index 36990e2e..21aea4d2 100644 --- a/src/CloudDataExplainer.vue +++ b/src/CloudDataExplainer.vue @@ -3,8 +3,8 @@ v-model="value" close-on-back close-on-esc - max-height="90%" scrollable + :fullscreen="fullscreen" > - - About Cloud Cover Data - Statistical Concepts - Weather Patterns - - - + + About Cloud Cover Data + Statistical Concepts + Weather Patterns +

- NASAs MODIS Aqua and Terra satellites - provide daily views of the entire surface of the Earth and measure the cloud cover. - This is provided as the cloud cover fraction - the percentage of the sky at a given location that is covered - by clouds. We are using MODIS Aqua cloud cover data product as provided by the - NASA Near Earth Observations (NEO) website. + NASA's Aqua and Terra satellites provide daily views of the entire surface of Earth. The MODIS instrument on these satellites helps scientists learn about conditions in our atmosphere and oceans. We display the calculated cloud cover fraction—the percentage of the sky at a given location that is covered by clouds—from MODIS (on the Aqua satellite), as provided by the NASA Near Earth Observations (NEO) website.

@@ -55,22 +40,20 @@ NASA provides the cloud cover data in 1-day, 8-day (and, not included, 30-day) averages.
  • The 1-day (daily) data maps display historic cloud cover for each April 8th from 2003 to 2023.
  • -
  • The 8-day average gives average of the 1-day data from April 7-14 from 2003 to 2023.
  • +
  • The 8-day maps display an average of the 1-day data from April 7-14 from 2003 to 2023.
- The daily data can have gaps and processing artefacts, so the 8-day average provides a more reliable measure of the cloud cover at every location on the map. - - Because weather can vary considerably from hour-to-hour and day-to-day, the longer interval of the 8-day average gives us more data - from which we can draw better conclusions about the possible weather conditions in a given location. -

- - - - +

+ If you compare the 1-day vs. the 8-day maps, you'll notice that the 1-day maps often have more data at the extreme ends, either mostly clear or cloudy. The 8-day maps tend to have more data concentrated in the middle bins of partly cloudy or mostly cloudy. If you average together days that are clear and cloudy, you will end up with something in the middle. The 1-day maps are not subject to this "smearing" effect of averaging over many days of data. +

+

+ The daily data can have gaps and processing artefacts, so the 8-day average provides a more reliable measure of the cloud cover at every location on the map. Because weather can vary considerably from hour-to-hour and day-to-day, the longer interval of the 8-day average gives us more data from which we can draw better conclusions about the possible weather conditions in a given location. +

+
How does the percent cloud cover relate to what I might see in a weather report?

- We group the percent cloud cover based on the bins from the National Weather Service: + We group the percent cloud cover based on the bins from the National Weather Service: @@ -96,16 +79,29 @@

+
+ Why use data from the Aqua satellite instead of Terra? +

+ We use data from the Aqua satellite because its cloud cover measurements are taken in the afternoon, which corresponds better to the time of day of the April Eclipse. +

+
Why is 2022 missing from the year list?

- Sometimes satellites go offline or there are issues transmitting data back to Earth. - On March 31, 2022 the MODIS Aqua satellite entered SAFE mode, only returning to normal operations on April 17, 2022. + Sometimes satellites go offline, or there are issues transmitting data back to Earth. + On March 31, 2022 the Aqua satellite entered SAFE mode, only returning to normal operations on April 17, 2022. - No cloud cover data is available from Mar 31 - Apr 16, 2022. View event summary. + No cloud cover data is available from Mar 31 - Apr 16, 2022. View the event summary. +

+
+
+ Why are 30-day maps not available? +

+ MODIS offers month-long averages of the data, but we opted not to include that here to improve performance and data load times.

+ @@ -118,7 +114,7 @@
What is a mean?

- The mean is the average of all values in the dataset. It is calculated by adding all the values together and dividing by the number of values. This is the statistic people are probably more familiar with and is often interpreted as a single value that “best” represents an entire data set. + The mean is the average of all values in the dataset. It is calculated by adding all the values together and dividing by the number of values. This is the statistical term people are probably more familiar with and is often interpreted as a single value that “best” represents an entire data set.

@@ -141,53 +137,51 @@
- mdi-chart-bar What is in the bar chart on the {{ smAndUp ? 'left' : 'top' }}? + mdi-chart-bar What is in the chart on the {{ smAndUp ? 'left' : 'top' }}?

- The left hand graph is called a histogram. For your selected location, it tells you how many years since 2003 were Clear, Partly Cloudy, Mostly Cloudy, or Cloudy at this location. If you have filtered the data by El Nino, Neutral, or La Nina years, your chosen subset will be colored with the blue to white gradient, while the rest of the years will appear gray. + The left hand graph is called a histogram. For your selected location, it tells you how many years since 2003 were Clear, Partly Cloudy, Mostly Cloudy, or Cloudy at this location. If you have filtered the data by El Niño, Neutral, or La Niña years, your chosen subset will be colored with the blue to white gradient, while the rest of the years will appear gray.

mdi-chart-scatter-plot What is in the graph on the {{ smAndUp ? 'right' : 'bottom' }}?

- The right hand graph is a scatter plot showing the cloud cover for your chosen location for each year since 2003. If you have filtered the data by El Nino, Neutral, or La Nina years, or for a single year, those data points will be displayed in yellow. The background of the graph shows what cloud cover values correspond to the weather conditions of Clear, Partly Cloudy, etc. + The right hand graph is a scatter plot showing the cloud cover for your chosen location for each year since 2003. If you have filtered the data by El Niño, Neutral, or La Niña years, or for a single year, those data points will be displayed in yellow. The background of the graph shows what cloud cover values correspond to the weather conditions of Clear, Partly Cloudy, etc.

-
- What is El Niño / La Niña? - You might have heard the terms El Niño or La Niña. - They refer to weather patterns that are associated with a slight warming (“El Niño”) or cooling (“La Niña”) of - the surface water in the Pacific Ocean relative to normal (“Neutral”). These are part of what is called the El Niño Southern Oscillation (ENSO) cycle. - These different conditions can impact weather worldwide, so we provide the option of filtering the historical cloud data based on these classifications. - Learn more about these fascinating weather phenomena from the NOAA National Ocean Service. -
+

+ You might have heard the terms El Niño or La Niña. They refer to weather patterns that are associated with a slight warming (“El Niño”) or cooling (“La Niña”) of the surface water in the Pacific Ocean relative to normal (“Neutral”). These are part of what is called the El Niño Southern Oscillation (ENSO) cycle. These different conditions can impact weather worldwide, so we provide the option of filtering the historical cloud data based on these classifications. Learn more about these fascinating weather phenomena from the NOAA National Ocean Service. +

- What years are El Niño, La Niña, or Neutral? - We use the NOAA list of past ENSO events to classify years as El Niño, La Niña, or Neutral. - Their list is based on the presence of an active El Niño or La Niña pattern during the months of December, January, and February. - As an ENSO typiclly last several months (or even years), this provides a decent indication a how likely April is to have the same pattern. - -

We duplicate a portion of the list below:

+ What years are considered El Niño, La Niña, or Neutral? +

+ We use NOAA's list of past ENSO events to classify years as El Niño, La Niña, or Neutral. As that page explains, there is not a single accepted way to define which of these categories we are in. + Their list is based on the presence of an active El Niño or La Niña pattern during the months of December, January, and February. As an ENSO typically last several months (or even years), this provides a decent indication a how likely April is to have the same pattern. +

+

For the years included in our data set, they classify them as follows:

Percentage
- + - - + + - - - + +
El Niño El Niño: 2003, 2007, 2010, 2016
La Niña2008, 2011, 2012, 2021, 2022 Neutral: 2004, 2005, 2006, 2009, 2013, 2014, 2015, 2017, 2018
Neutral2004, 2005, 2006, 2009, 2013, 2014, 2015, 2017, 2018 La Niña: 2008, 2011, 2012, 2021, 2022, 2023
+

+

+ If you want to see what the ENSO conditions were in March/April in the past, see the "MEI.v2 Values" at this NOAA website. +

@@ -205,7 +199,7 @@ - Close + Close
@@ -230,6 +224,11 @@ export default defineComponent({ initialTab: { type: String as () => Tab, default: 'intro' + }, + + fullscreen: { + type: Boolean, + default: false } }, @@ -265,7 +264,6 @@ export default defineComponent({ strong { font-weight: bold; - color: #eac402; } h3 { @@ -306,6 +304,9 @@ details.faq { .no-text-transform { text-transform: none !important; + height: 1rem; + text-align: left; + white-space: pre-wrap; } @@ -316,5 +317,8 @@ details.faq { right: 0.125em; } +.selected-tab { + background-color: #eac3021d; +} \ No newline at end of file diff --git a/src/LocationSelector.vue b/src/LocationSelector.vue index e6573358..b0bb254e 100644 --- a/src/LocationSelector.vue +++ b/src/LocationSelector.vue @@ -51,7 +51,7 @@ interface CloudData { export default defineComponent({ - emits: ["place", "update:modelValue", "error", "dataclick"], + emits: ["place", "update:modelValue", "error", "dataclick", "finishLoading"], props: { @@ -203,6 +203,7 @@ export default defineComponent({ return; } this.cloudCoverRectangles.addTo(this.map as Map); // Not sure why, but TS is cranky w/o the Map cast + this.$emit('finishLoading'); }, @@ -330,13 +331,11 @@ export default defineComponent({ const initialZoom = this.mapOptions.initialZoom ?? 4; const zoom = initial ? initialZoom : (this.map?.getZoom() ?? initialZoom); const map = L.map(mapContainer, {renderer: new L.Canvas()}).setView(location, zoom); - + const options = { ...defaultMapOptions, ...this.mapOptions }; this.basemap = L.tileLayer(options.templateUrl, options); this.basemap.addTo(map); - this.updateCloudCover(this.showCloudCover); - this.bringLocationAndPathToFront(); this.placeCircles = this.places.map(place => this.circleForPlace(place)); this.placeCircles.forEach((circle, index) => { @@ -412,6 +411,9 @@ export default defineComponent({ this.selectedCircle?.bringToFront(); this.map = map; + + this.updateCloudCover(this.showCloudCover); + this.bringLocationAndPathToFront(); }, updateValue(value: LocationDeg) { diff --git a/src/SolarEclipse2024.vue b/src/SolarEclipse2024.vue index ef6b68fe..91ae36a0 100644 --- a/src/SolarEclipse2024.vue +++ b/src/SolarEclipse2024.vue @@ -56,7 +56,7 @@ >View Historical Cloud Data Explore Historical Cloud Data + >Explore Detailed Cloud Data
@@ -114,6 +114,7 @@ class="mr-2 mb-2" v-if="infoPage==1" density="compact" + hide-details :color="accentColor" @click="infoPage++" @keyup.enter="infoPage++" @@ -139,7 +140,7 @@
- This map shows historical cloud cover data for the week of April 8 for the years 2003–2023 from the NASA MODIS Aqua satellite. + This map shows historical cloud cover data for the week of April 8 for the years 2003–2023 from MODIS on NASA's Aqua satellite. {{ touchscreen ? "Tap" : "Click" }} the map to display the cloud coverage for a particular location (within about 100 km).
@@ -160,7 +161,7 @@

Explore whether phenomena like El Niño historically impacted cloud cover patterns.

-
Open the Cloud Date Explorer
+
Open the Cloud Data Explorer
@@ -462,53 +463,81 @@ >

Time Controls:

(Bottom-left of the screen)

+

+ By default, time is moving forward at 100x the real speed. Time slows down to 10x the real speed as the eclipse approaches totality. +

  • {{ touchscreen ? "Tap" : "Click" }} - to move time forward at 100x the real speed. Time slows down to 10x the real speed as the eclipse approaches totality. + to reverse time, or to increase reverse speed by 10x if time was already reversed.
  • - If playing, {{ touchscreen ? "tap" : "click" }} - to pause time. + {{ touchscreen ? "Tap" : "Click" }} / + + to play or pause time.
  • {{ touchscreen ? "Tap" : "Click" }} - to decrease speed by 10x. + class="bullet-icon" + icon="angles-right" + size="lg" + > + to increase speed by 10x, or to move time forward if time was reversed.
  • {{ touchscreen ? "Tap" : "Click" }} - to increase speed by 10x. + to reset starting time and speed.
  • {{ touchscreen ? "Tap" : "Click" }} - to reset time, view, and speed. + to open more speed controls.
  • +
      +
    • + {{ touchscreen ? "Tap" : "Click" }} + + + or + + + to move time forward and backward. +
    • +
    • + Use the slider to fine-tune desired speed. +
    • +
  • Drag along the slider to move to any time. + > along the main slider to move to any time.
@@ -519,21 +548,22 @@
  • The selected location + font-weight: bold ">historical cloud cover, historical cloud cover - and date/time, and + date/time are displayed under the map. + font-weight: bold ">selected location + are displayed under the map.
  • Display Options:

(Bottom-right of the screen)

    +
  • + Center Sun: Recenter view on Sun. +
  • Sky Grid: Display altitude/azimuth grid with cardinal directions.
  • @@ -589,6 +622,13 @@

    Location Options:

    (Top-left of the screen)

      +
    • + {{ touchscreen ? "Tap" : "Click" }} to search for a specific location name. +
    • {{ touchscreen ? "Tap" : "Click" }}
      - +
      +
      + + + +
      +
      +
      + {{ feature.place_name }} +
      +
      +
      + + + New! Location Search + View historical cloud data - Detailed Cloud Data View + New! Detailed cloud explorer - View historical cloud data for the week of April 8th from 2003–2023. New: View detailed 0.5o cloud data including by presence of El Niño/La Niña climate patterns. + View historical cloud data for the week of April 8th from 2003–2023. + + + + NEW! Explore historical cloud data as individual years or filter by El Niño/La Niña climate patterns.