diff --git a/01_Data_raw/Water_Quality/Guana_WQ/guana_data_dictionary_updateGK.csv b/01_Data_raw/Water_Quality/Guana_WQ/guana_data_dictionary_updateGK.csv
index 92d4b8e..1fd73a0 100644
--- a/01_Data_raw/Water_Quality/Guana_WQ/guana_data_dictionary_updateGK.csv
+++ b/01_Data_raw/Water_Quality/Guana_WQ/guana_data_dictionary_updateGK.csv
@@ -1,4 +1,4 @@
-site,alternate_name,site_friendly,station_code,site_acronym,lat,long,start_date,end,wbid,location
+site,alternate_name,site_friendly,station_code,site_acronym,Latitude,Longitude,start_date,end,wbid,location
MICKLERS,N,Micklers,GTMMKNUT,MK,30.16073611,-81.36027778,,N,Lake,water_control
DEPGL1,N,Guana Lake 1,GTMGL1NUT,GL1,30.1504,-81.3604,,N,Lake,open_water
DEPGL2,N,Guana Lake 2,GTMGL2NUT,GL2,30.1161,-81.3511,,N,Lake,open_water
diff --git a/01_Data_raw/Water_Quality/Guana_WQ/~$Guana_masterdata.xlsx b/01_Data_raw/Water_Quality/Guana_WQ/~$Guana_masterdata.xlsx
new file mode 100644
index 0000000..5a93205
Binary files /dev/null and b/01_Data_raw/Water_Quality/Guana_WQ/~$Guana_masterdata.xlsx differ
diff --git a/02_Cleaning_scripts/WIN_data_clean.R b/02_Cleaning_scripts/WIN_data_clean.R
index 1182e36..383161c 100644
--- a/02_Cleaning_scripts/WIN_data_clean.R
+++ b/02_Cleaning_scripts/WIN_data_clean.R
@@ -9,7 +9,14 @@ library(tidyverse)
GTMNERR <- st_read("03_Data_for_app/shapefiles_new/counties_GTMNERR.shp")
# CRS: NAD83 / UTM zone 17N
# WIN Data
-gps_data <- read.csv("./01_Data_raw/Water_Quality/WIN/WIN_data_merged_20240501.csv")
+gps_data <- read_csv("./01_Data_raw/Water_Quality/WIN/WIN_data_merged_20240501.csv")
+
+lookup_names <- read_csv("03_Data_for_app/WQ_lookup_names.csv")
+
+# Change column names so we can later merge this with other WQ data
+recode_vec <- setNames(lookup_names$original_name, lookup_names$dashboard_name)
+gps_data <- gps_data %>%
+ rename(any_of(recode_vec))
#### GTMNERR boundary and aquatic preserves ####
@@ -41,7 +48,7 @@ bound_box <- st_bbox(st_sfc(pt1, pt3, pt4, pt2, crs = st_crs(GTMNERR)))
# Filter GPS coordinates
# Convert to sf object
-gps_sf <- st_as_sf(gps_data, coords = c("Location_2", "Location_1"), crs = 4326)
+gps_sf <- st_as_sf(gps_data, coords = c("Longitude", "Latitude"), crs = 4326)
# Crop GPS points within the bounding box
gps_cropped <- st_crop(gps_sf, bound_box)
@@ -65,7 +72,7 @@ coordinates <- st_coordinates(gps_cropped)
WIN_df <- cbind(WIN_df, coordinates)
# Rename the coordinates columns if necessary
-colnames(WIN_df)[(ncol(WIN_df)-1):ncol(WIN_df)] <- c("longitude", "latitude")
+colnames(WIN_df)[(ncol(WIN_df)-1):ncol(WIN_df)] <- c("Longitude", "Latitude")
#### Keep only columns with varying information ####
# Function to remove columns with the same value in the whole column
@@ -83,15 +90,17 @@ WIN_df <- remove_constant_columns(WIN_df)
# Convert all columns to character before pivoting and retain the original row identifier
WIN_df <- WIN_df %>%
- select(-all_of(c("Station.ID",
- "Station.Name",
- "Org.Analyte.Name",
- "DEP.Result.Value.Number",
- "DEP.MDL",
- "DEP.PQL",
- "Org.Detection.Unit",
- "Org.Result.Unit",
- "Activity.End.Date.Time"))) %>%
+ select(-all_of(c("StationID",
+ "StationName",
+ "OrgAnalyteName",
+ "OrgResultValue", #GK: changed this from "DEPResultValueNumber", as I believe it is the DEP value we want to keep?
+ "DEPMDL",
+ "DEPPQL",
+ "OrgDetectionUnit",
+ "OrgResultUnit",
+ "ActivityEndDateTime"))) %>%
+ # Add a column to record the data source/provider
+ mutate(data_source = "WIN") %>% # or change this to DEP?
mutate(across(everything(), as.character)) %>%
mutate_all(~ na_if(., "")) %>%
pivot_longer(
@@ -108,4 +117,5 @@ WIN_df <- WIN_df %>%
# "03_Data_for_app/Filtered_WIN_data_merged_20240501.csv",
# row.names = FALSE)
# Save the filtered data to a .RDs file
+
saveRDS(WIN_df, "03_Data_for_app/WIN.Rds")
diff --git a/02_Cleaning_scripts/WQ_GTMNERR.R b/02_Cleaning_scripts/WQ_GTMNERR.R
index 4010ff2..99c1a26 100644
--- a/02_Cleaning_scripts/WQ_GTMNERR.R
+++ b/02_Cleaning_scripts/WQ_GTMNERR.R
@@ -28,6 +28,13 @@ WQ_meta <- read_csv("01_Data_raw/Water_Quality/Guana_WQ/guana_data_dictionary_up
# Some stations have two codes due to a name change (see Word doc with metadata)
# Don't remove
+lookup_names <- read_csv("03_Data_for_app/WQ_lookup_names.csv")
+
+# Change column names so we can later merge this with other WQ data
+recode_vec <- setNames(lookup_names$original_name, lookup_names$dashboard_name)
+WQ <- WQ %>%
+ rename(any_of(recode_vec))
+
### 2. Check categorical values ------------------------------------------------
# Check station names, componentLong and componentShort (spelling etc)
unique(WQ$StationCode)
@@ -61,24 +68,23 @@ unique(WQ$Remark) # inconsistent... But there are some capital letters that
names(WQ_meta)[names(WQ_meta) == "station_code"] <- "StationCode"
WQ <- WQ %>%
- left_join(WQ_meta) %>%
- select(-Lat, -Long)
+ left_join(WQ_meta)
# Stations missing from metadata: GL1.5, GL2.5 and GL3.5 -> added manually and
# emailed Nikki
-which(is.na(WQ$lat))
-which(is.na(WQ$long))
+which(is.na(WQ$Latitude))
+which(is.na(WQ$Longitude))
-WQ[which(is.na(WQ$lat)),] # duplicates?? Remove for now; emailed Nikki
-WQ <- WQ[-which(is.na(WQ$lat)),]
+WQ[which(is.na(WQ$Latitude)),] # duplicates?? Remove for now; emailed Nikki
+WQ <- WQ[-which(is.na(WQ$Latitude)),]
# Create a separate dataframe with only station info, not the data (makes map
# too heavy)
WQ_locations <- WQ %>%
mutate(Year = year(SampleDate)) %>%
- select(site_friendly, Year, site_acronym, lat, long, wbid, location) %>%
- group_by(site_friendly, site_acronym, lat, long, wbid, location) %>%
+ select(site_friendly, Year, site_acronym, Latitude, Longitude, wbid, location) %>%
+ group_by(site_friendly, site_acronym, Latitude, Longitude, wbid, location) %>%
summarize(maxYear = max(Year), minYear = min(Year)) %>%
mutate(type = "Water quality",
dataset = "Guana Water Quality Monitoring (GTMNERR)")
@@ -86,7 +92,7 @@ WQ_locations <- WQ %>%
WQ_data_available <- WQ %>%
mutate(Year = year(SampleDate)) %>%
select(StationCode, Year, SampleType, ComponentShort, ComponentLong, site_friendly,
- site_acronym, lat, long, wbid, location) %>%
+ site_acronym, Latitude, Longitude, wbid, location) %>%
distinct()
### 4. Save data ---------------------------------------------------------------
diff --git a/02_Cleaning_scripts/WQ_WIN_merge.R b/02_Cleaning_scripts/WQ_WIN_merge.R
new file mode 100644
index 0000000..9738bb5
--- /dev/null
+++ b/02_Cleaning_scripts/WQ_WIN_merge.R
@@ -0,0 +1,67 @@
+########################################################################
+########## NERRS Science Transfer project - GTMNERR #############
+########################################################################
+
+# Geraldine Klarenberg, PhD
+# gklarenberg@ufl.edu
+# 12 August 2024
+
+# Load packages
+library(tidyverse)
+
+# Merge WIN and WQ data into one
+
+WIN <- readRDS("03_Data_for_app/WIN.Rds")
+WQ_GTMNERR <- readRDS("03_Data_for_app/WQ.Rds")
+
+# Make WQ_GTMNERR long format as well, just like WIN
+# Having a column for the dates is advisable though, as it is a separate data
+# type. Update that later, not right now.
+
+# First make sure that every row has a UNID and also add a column for the data
+# source / provider
+WQ_GTMNERR <- WQ_GTMNERR %>%
+ mutate(data_source = "GTMNERR") %>%
+ arrange(UNID, StationCode, SampleDate, ComponentShort)
+
+for (i in 1:nrow(WQ_GTMNERR)){
+ if (is.na(WQ_GTMNERR$UNID[i])){
+ WQ_GTMNERR$UNID[i] <- WQ_GTMNERR$UNID[i-1] + 1
+ }
+}
+# Check there are no duplicates
+sum(duplicated(WQ_GTMNERR$UNID))
+
+# Add a geometry column, to later use for clicking markers (we might change this)
+WQ_GTMNERR <- st_as_sf(WQ_GTMNERR, coords = c("Longitude", "Latitude"),
+ crs = 4326, remove = FALSE)
+# Turn back into dataframe with geometry as a column
+WQ_GTMNERR <- as.data.frame(WQ_GTMNERR)
+
+WQ_GTMNERR_long <- WQ_GTMNERR %>%
+ mutate(across(everything(), as.character)) %>%
+ mutate_all(~ na_if(., "")) %>%
+ pivot_longer(cols = -UNID,
+ names_to = "variable",
+ values_to = "value")
+
+# How to deal with UNID when merging? Start counting anew (or add however far the
+# one dataset is?)
+
+min(as.numeric(WQ_GTMNERR_long$UNID)) # 1
+max(as.numeric(WQ_GTMNERR_long$UNID)) # 5016 (used to be 17098?)
+
+min(as.numeric(WIN$RowID)) # 55135
+max(as.numeric(WIN$RowID)) # 3677602
+# Appears there will be no overlap. Merge.
+
+WQ_GTMNERR_long <- WQ_GTMNERR_long %>%
+ rename(RowID = UNID)
+
+WQ_all <- WIN %>%
+ full_join(WQ_GTMNERR_long)
+
+unique(WQ_all$variable)
+
+# Save data
+saveRDS(WQ_all, "03_Data_for_app/WQ_all.Rds")
diff --git a/03_Data_for_app/WIN.Rds b/03_Data_for_app/WIN.Rds
index 001f3d9..f093579 100644
Binary files a/03_Data_for_app/WIN.Rds and b/03_Data_for_app/WIN.Rds differ
diff --git a/03_Data_for_app/WQ.Rds b/03_Data_for_app/WQ.Rds
index 37f790a..3b7dd4a 100644
Binary files a/03_Data_for_app/WQ.Rds and b/03_Data_for_app/WQ.Rds differ
diff --git a/03_Data_for_app/WQ_all.Rds b/03_Data_for_app/WQ_all.Rds
new file mode 100644
index 0000000..dc4b1c9
Binary files /dev/null and b/03_Data_for_app/WQ_all.Rds differ
diff --git a/03_Data_for_app/WQ_locations.Rds b/03_Data_for_app/WQ_locations.Rds
index 524f726..85e010a 100644
Binary files a/03_Data_for_app/WQ_locations.Rds and b/03_Data_for_app/WQ_locations.Rds differ
diff --git a/03_Data_for_app/WQ_lookup_names.csv b/03_Data_for_app/WQ_lookup_names.csv
new file mode 100644
index 0000000..95ac485
--- /dev/null
+++ b/03_Data_for_app/WQ_lookup_names.csv
@@ -0,0 +1,111 @@
+data_source,original_name,dashboard_name
+WIN,Organization ID,OrganizationID
+WIN,Monitoring Location ID,MonitoringLocationID
+WIN,HUC12 Name,HUC12Name
+WIN,Project ID,ProjectID
+WIN,Activity ID,ActivityID
+WIN,Activity Type,SampleType
+WIN,Activity Start Date Time,SampleDate
+WIN,Activity End Date Time,ActivityEndDateTime
+WIN,Activity Time Zone,ActivityTimeZone
+WIN,Media,Media
+WIN,Matrix,Matrix
+WIN,Sample Collection Type,SampleCollectionType
+WIN,Sampling Agency Name,SamplingAgencyName
+WIN,SampleCollectionEquipmentName,SampleCollectionEquipmentName
+WIN,Activity Depth,ActivityDepth
+WIN,Activity Depth Unit,ActivityDepthUnit
+WIN,Relative Depth,RelativeDepth
+WIN,Activity Top Depth,ActivityTopDepth
+WIN,Activity Bottom Depth,ActivityBottomDepth
+WIN,Activity Depth Top Bottom Unit,ActivityDepthTopBottomUnit
+WIN,Total Depth,TotalDepth
+WIN,Total Depth Unit,TotalDepthUnit
+WIN,Activity Representative Ind,ActivityRepresentativeInd
+WIN,Activity Comments,ActivityComments
+WIN,Sampler Name,SamplerName
+WIN,Field Blank Batch ID,FieldBlankBatchID
+WIN,Equipment Blank Batch ID,EquipmentBlankBatchID
+WIN,Trip Blank Batch ID,TripBlankBatchID
+WIN,Master Activity ID,MasterActivityID
+WIN,Activity Loaded Date,ActivityLoadedDate
+WIN,Activity Updated Date,ActivityUpdatedDate
+WIN,DEP Result ID,DEPResultID
+WIN,Org Result ID,OrgResultID
+WIN,DEP Analyte Group,DEPAnalyteGroup
+WIN,DEP Analyte Name,ComponentLong
+WIN,ADaPT Analyte ID,ADaPTAnalyteID
+WIN,Org Analyte Name,OrgAnalyteName
+WIN,Org Result Value,OrgResultValue
+WIN,Org Result Unit,OrgResultUnit
+WIN,Org MDL,OrgMDL
+WIN,Org PQL,OrgPQL
+WIN,Org Detection Unit,OrgDetectionUnit
+WIN,DEP Result Value Number,Result
+WIN,DEP Result Value Text,DEPResultValueText
+WIN,DEP Result Unit,Unit
+WIN,DEP MDL,DEPMDL
+WIN,DEP PQL,DEPPQL
+WIN,Value Qualifier,ValueQualifier
+WIN,Sample Fraction,SampleFraction
+WIN,Prep Method,PrepMethod
+WIN,Preparation Date Time,PreparationDateTime
+WIN,Preparation Time Zone,PreparationTimeZone
+WIN,Analysis Method,AnalysisMethod
+WIN,Analysis Date Time,AnalysisDateTime
+WIN,Analysis Time Zone,AnalysisTimeZone
+WIN,Lab ID,LabID
+WIN,Lab Name,LabName
+WIN,Lab Accreditation Authority,LabAccreditationAuthority
+WIN,Result Comments,ResultComments
+WIN,Lab Sample ID,LabSampleID
+WIN,Method Batch ID,MethodBatchID
+WIN,Analytical Batch ID,AnalyticalBatchID
+WIN,Dilution,Dilution
+WIN,Percent Moisture,PercentMoisture
+WIN,Percent Recovery,PercentRecovery
+WIN,Relative Percent Difference,RelativePercentDifference
+WIN,Error,Error
+WIN,Target Species,TargetSpecies
+WIN,Finfish Size,FinfishSize
+WIN,Finfish Unit,FinfishUnit
+WIN,Result Value Type,ResultValueType
+WIN,Statistical Base,StatisticalBase
+WIN,Audit Censored Decisions,AuditCensoredDecisions
+WIN,Result Loaded Date,ResultLoadedDate
+WIN,Result Updated Date,ResultUpdatedDate
+WIN,RowID,RowID
+WIN,LocationID,LocationID
+WIN,ProgramID,ProgramID
+WIN,Station ID,StationID
+WIN,Station Name,StationName
+WIN,Station Type,StationType
+WIN,County,County
+WIN,Start Date,StartDate
+WIN,End Date,EndDate
+WIN,Location_1,Latitude
+WIN,Location_2,Longitude
+GTMNERR,UNID,UNID
+GTMNERR,StationCode,StationCode
+GTMNERR,SampleDate,SampleDate
+GTMNERR,SampleType,SampleType
+GTMNERR,Lat,Latitude
+GTMNERR,Long,Longitude
+GTMNERR,ComponentShort,ComponentShort
+GTMNERR,ComponentLong,ComponentLong
+GTMNERR,Result,Result
+GTMNERR,Remark,Remark
+GTMNERR,Flag,Flag
+GTMNERR,Unit,Unit
+GTMNERR,MRL,MRL
+GTMNERR,MDL,MDL
+GTMNERR,Dilution,Dilution
+GTMNERR,PQL,PQL
+GTMNERR,DateRecieved,DateRecieved
+GTMNERR,DateAnalyzed,DateAnalyzed
+GTMNERR,TestComments,TestComments
+GTMNERR,AnalysisMethod,AnalysisMethod
+GTMNERR,Lab ID,LabID
+GTMNERR,Lab Accredidation Authority,LabAccredidationAuthority
+GTMNERR,Laboratory,Laboratory
+GTMNERR,RQ#,RQ#
\ No newline at end of file
diff --git a/03_Data_for_app/lookup_creation_manual.txt b/03_Data_for_app/lookup_creation_manual.txt
new file mode 100644
index 0000000..54778df
--- /dev/null
+++ b/03_Data_for_app/lookup_creation_manual.txt
@@ -0,0 +1,16 @@
+Guana Dashboard development
+13 August 2024
+
+For the water quality page, to streamline showing all the WQ data on one page, I manually created
+a lookup table to change the headers of the separate files so they are the same. This way we can use
+merge the datasets and use the existing functions on them.
+
+The headers comfr from the files App_dev/01_Data_raw/Water_Quality/WIN/WIN_data_merged_20240501.csv and
+App_dev/01_Data_raw/Water_Quality/Guana_WQ/Guana_masterdata.xlsx.
+
+1. Copy-pasted the header names to App_dev/03_Data_for_app/WQ_lookup_names.csv and named the column original_name
+2. Added a column data_sources with either WIN or GTMNERR
+3. Created a column dashboard_name and copied all the names from original_name to it
+4. For now (08/13/2024) I am only changing latitude, longitude, dates, sample type, components/analytes measured (DEP, not org). For visualization purposes. We can rename the rest later (analytes themselves will
+also need to be renamed, as well as info on station names and types).
+5. For the new names I also removed the spaces (because R inserts points there).
\ No newline at end of file
diff --git a/04_Tests/leaflet_test.R b/04_Tests/leaflet_test.R
index c125916..baf9dd6 100644
--- a/04_Tests/leaflet_test.R
+++ b/04_Tests/leaflet_test.R
@@ -17,7 +17,7 @@ GTMNERR <- st_transform(GTMNERR, crs = 4326)
# Leaflet uses EPSG 3857, change this
# https://gis.stackexchange.com/questions/48949/epsg-3857-or-4326-for-web-mapping
-epsg4326 <- leafletCRS(crsClass = "L.CRS.EPSG4326")
+#epsg4326 <- leafletCRS(crsClass = "L.CRS.EPSG4326")
# BUT! It actually seems that Leaflet does still want shapefiles in 4326, see
# https://github.com/Leaflet/Leaflet/issues/4146 I also tried to change GTMNERR
# to crs 3857 but that threw errors. See second paragraph here:
@@ -27,11 +27,11 @@ m <- leaflet(data = GTMNERR,
options = leafletOptions(#crs = epsg4326,
minZoom = 9,
maxZoom = 18)) %>%
- #setView(lng=-81.347388, lat=30.075, zoom = 11) %>%
+ setView(lng=-81.289, lat=29.905, zoom = 11) %>%
clearBounds() %>%
addTiles() %>% # Add default OpenStreetMap map tiles
- addPolygons(color = "purple", fill = NA) #%>%
- #addMarkers(lng=-81.347388, lat=30.075, popup="Guana")
+ addPolygons(color = "purple", fill = NA) %>%
+ addMarkers(lng=-81.347388, lat=30.075, popup="Guana")
m
counties_select <- st_read("03_Data_for_app/shapefiles_new/counties_GTMNERR.shp")
@@ -43,7 +43,7 @@ HAB_data_locations <- HAB_data %>%
distinct() %>%
st_as_sf(coords = c("Longitude", "Latitude"), crs = 4326)
-leaflet(options = leafletOptions(crs = epsg4326, minZoom = 9, maxZoom = 18)) %>%
+leaflet(options = leafletOptions(minZoom = 9, maxZoom = 18)) %>%
setView(lng=-81.347388, lat=30.075, zoom = 11) %>%
# Base map
addTiles() %>% # Add default OpenStreetMap map tiles
@@ -56,10 +56,15 @@ leaflet(options = leafletOptions(crs = epsg4326, minZoom = 9, maxZoom = 18)) %>%
highlightOptions = highlightOptions(color = "white", weight = 2,
bringToFront = TRUE),
group = "Counties", popup = ~NAME) %>%
- addMarkers(data = HAB_data_locations,
- popup = ~paste("Site: ", Site, "
",
- "County: ", County),
- group = "HAB") %>%
+ addAwesomeMarkers(icon = makeAwesomeIcon(icon = "flask", markerColor = "blue", library = "fa",
+ iconColor = "black"), #"",
+ data = HAB_data_locations,
+ #lng= rep(-81.347388, 34), lat = rep(30.075,34)
+ ) %>%
+ # addMarkers(data = HAB_data_locations,
+ # popup = ~paste("Site: ", Site, "
",
+ # "County: ", County),
+ # group = "HAB") %>%
# # Layers control (turning layers on and off)
addLayersControl(overlayGroups = c("Counties", "GTMNERR boundaries", "HAB"),
options = layersControlOptions(collapsed = FALSE))
diff --git a/app.R b/app.R
index 39efe18..13da537 100644
--- a/app.R
+++ b/app.R
@@ -1,40 +1,44 @@
-# This is the main app page, which will run and read in all the other pages
-# and modules, and render the dashboard
-
-# Note: not necessary to load packages here: this all happens in global.R
-
-source("global.R")
-source("functions.R")
-source("modules/main_page.R")
-source("modules/waterquality.R")
-source("modules/algae.R")
-source("modules/win.R")
-
-ui <- dashboardPage(
- dashboardHeader(title = "Guana River Data Dashboard"),
- dashboardSidebar(
- sidebarMenu(id = "tabs",
- menuItem("Main Page", tabName = "main_page", icon = icon("home")),
- menuItem("Water Quality Data", tabName = "waterquality", icon = icon("link")),
- menuItem("Harmful Algal Bloom Data", tabName = "algae", icon = icon("link")),
- menuItem("Water Information Network", tabName = "win", icon = icon("bridge-water", lib="font-awesome"))
- )
- ),
- dashboardBody(
- tabItems(
- tabItem(tabName = "main_page", mainPageUI(id = "main_page")),
- tabItem(tabName = "waterquality", WQPageUI(id = "waterquality")),
- tabItem(tabName = "algae", HABPageUI(id = "algae")),
- tabItem(tabName = "win", WINPageUI(id = "win"))
- )
- )
-)
-
-server <- function(input, output, session) {
- moduleServer(module = mainPageServer, id = "main_page", session = session)
- WQPageServer("waterquality", parentSession = session)
- HABPageServer("algae", parentSession = session)
- WINPageServer("win", parentSession = session)
-}
-
-shinyApp(ui, server)
+# This is the main app page, which will run and read in all the other pages
+# and modules, and render the dashboard
+
+# Note: not necessary to load packages here: this all happens in global.R
+
+source("global.R")
+source("functions.R")
+source("modules/main_page.R")
+source("modules/waterquality.R")
+source("modules/algae.R")
+#source("modules/win.R")
+
+ui <- dashboardPage(
+ dashboardHeader(title = "Guana River Data Dashboard"),
+ dashboardSidebar(
+ sidebarMenu(id = "tabs",
+ menuItem("Main Page", tabName = "main_page", icon = icon("home")),
+ #menuItem("Water Quality Data", tabName = "waterquality", icon = icon("link")),
+ menuItem("Harmful Algal Bloom Data", tabName = "algae", icon = icon("microscope", lib = "font-awesome")),
+ menuItem("Water Quality Data", tabName = "waterquality", icon = icon("flask-vial", lib="font-awesome")),
+ menuItem("Water Level Data", tabName = "waterlevel", icon = icon("water", lib="font-awesome")),
+ menuItem("Fish, Shellfish & Other Aquatic Organisms Data", tabName = "shellfish", icon = icon("fish", lib="font-awesome")),
+ menuItem("Terrestrial Animal Data", tabName = "animal", icon = icon("paw", lib="font-awesome")),
+ menuItem("Vegetation Data", tabName = "animal", icon = icon("seedling", lib="font-awesome"))
+ )
+ ),
+ dashboardBody(
+ tabItems(
+ tabItem(tabName = "main_page", mainPageUI(id = "main_page")),
+ #tabItem(tabName = "waterquality", WQPageUI(id = "waterquality")),
+ tabItem(tabName = "algae", HABPageUI(id = "algae")),
+ tabItem(tabName = "waterquality", WINPageUI(id = "waterquality"))
+ )
+ )
+)
+
+server <- function(input, output, session) {
+ moduleServer(module = mainPageServer, id = "main_page", session = session)
+ #WQPageServer("waterquality", parentSession = session)
+ HABPageServer("algae", parentSession = session)
+ WINPageServer("waterquality", parentSession = session)
+}
+
+shinyApp(ui, server)
diff --git a/modules/main_page.R b/modules/main_page.R
index f35ec56..14d5afc 100644
--- a/modules/main_page.R
+++ b/modules/main_page.R
@@ -1,3 +1,14 @@
+########################################################################
+########## NERRS Science Transfer project - GTMNERR #############
+########################################################################
+
+# Geraldine Klarenberg, PhD
+# gklarenberg@ufl.edu
+# Created June 2024
+# Last updated: 12 August 2024
+
+# This page shows a map, with a dropdown menu to pick types of
+# datasets, as well as shapefiles for the area
#### Get WIN data locations
# I am putting this here right now, but I feel we should move this to a cleaning
@@ -7,10 +18,10 @@ WIN_df <- readRDS("./03_Data_for_app/WIN.Rds")
WIN_data_locations = WIN_df %>%
filter(variable %in% c("geometry",
- "HUC12.Name",
- "Start.Date",
- "latitude",
- "longitude")
+ "HUC12Name",
+ "SampleDate",
+ "Latitude",
+ "Longitude")
) %>%
select(c(RowID, variable, value)) %>%
distinct(RowID, variable, value) %>%
@@ -19,24 +30,32 @@ WIN_data_locations = WIN_df %>%
values_from = value,
values_fill = list(value = NA)
) %>%
- distinct(geometry, HUC12.Name, Start.Date, latitude, longitude) %>%
+ distinct(geometry, HUC12Name, SampleDate, Latitude, Longitude) %>%
mutate(
- lat = as.numeric(latitude),
- long = as.numeric(longitude),
+ SampleDate = ymd_hms(SampleDate),
+ Latitude = as.numeric(Latitude),
+ Longitude = as.numeric(Longitude),
type = "Water quality",
- dataset = "Watershed Information Network (DEP)"
+ dataset = "Watershed Information Network (DEP)", # Update this so we use data_source
+ minYear = min(year(SampleDate)),
+ maxYear = max(year(SampleDate))
) %>%
- select(-geometry, - latitude, -longitude)
+ select(-geometry, -SampleDate)
#### WQ locations data ------------------------------------------------
WQ_data_locations <- readRDS("./03_Data_for_app/WQ_locations.Rds")
# For now, for testing, make WQ_locations the dataframe to be used for filtering
datasets_location <- full_join(WQ_data_locations, WIN_data_locations)
-datasets_location <- st_as_sf(datasets_location, coords = c("long", "lat"), crs = 4326)
+datasets_location <- st_as_sf(datasets_location, coords = c("Longitude", "Latitude"), crs = 4326)
+datasets_location <- datasets_location[!duplicated(datasets_location),]
+
+color_palette <- colorFactor(palette = c("red", "goldenrod1"), #, "blue", "green"
+ domain = datasets_location$dataset)
-color_palette <- colorFactor(palette = c("red"), #, "blue", "green", "purple"
- domain = datasets_location$type)
+#### HAB locations data ------------------------------------------------
+# Add this at some point so there is another dataset that shows up in the dropdown
+# menu
### Define the UI -------------------------------------------------------------
mainPageUI <- function(id) {
@@ -79,8 +98,8 @@ mainPageServer <- function(input, output, session) {
# Create the map
output$map <- renderLeaflet({
leaflet(options = leafletOptions(minZoom = 9, maxZoom = 18)) %>%
- #setView(lng=-81.347388, lat=30.075, zoom = 11) %>%
- clearBounds() %>% # centers map on all min/max coords
+ setView(-81.289, lat=29.905, zoom = 10) %>%
+ #clearBounds() %>% # centers map on all min/max coords
# Base map
addTiles() %>% # Add default OpenStreetMap map tiles
# Polygons, add groups
@@ -127,25 +146,28 @@ mainPageServer <- function(input, output, session) {
observeEvent(input$datatype_selector, {
# Filter data based on selected group
filtered_data <- datasets_location[datasets_location$type == input$datatype_selector,]
-
+ print(filtered_data)
# Add markers to the map - commented out the popup bc this only works for WQ data
print("Adding markers")
leafletProxy(ns("map")) %>%
clearMarkers() %>%
- addCircleMarkers(
- data = filtered_data,
- color = ~color_palette(type),
- opacity = 1,
- fillOpacity = 0.5,
- fillColor = ~color_palette(type),
- fill = TRUE,
- weight = 3,
- radius = 8,
- # popup = ~paste("Station: ", site_friendly, "
",
- # "Location: ", wbid, "
",
- # "Latest year of sampling: ", maxYear, "
%
+ # addCircleMarkers(
+ # data = filtered_data,
+ # color = ~color_palette(dataset),
+ # opacity = 1,
+ # fillOpacity = 0.5,
+ # fillColor = ~color_palette(dataset),
+ # fill = TRUE,
+ # weight = 3,
+ # radius = 8,
+ # popup = ~paste("Station: ", site_friendly, "
",
+ # "Location: ", wbid, "
",
+ # "Latest year of sampling: ", maxYear, "
%
- st_as_sf(coords = c("long", "lat"), crs = 4326)
+########################################################################
+########## NERRS Science Transfer project - GTMNERR #############
+########################################################################
-#### WQ data ------------------------------------------------
-WQ <- readRDS("./03_Data_for_app/WQ.Rds")
+# Geraldine Klarenberg, PhD
+# Email: gklarenberg@ufl.edu
+# Christopher Marais
+# Email:
+# Last updated: 12 August 2024
-WQPageUI <- function(id) {
- ns <- NS(id) # This is an important part to add to all sub pages so they use the
- # correct sessions / ID's that connect the ui and server here
+library(tidyverse)
+
+# import all WQ data for this page (WIN and Guana spreadsheet)
+WQ_df <- readRDS("./03_Data_for_app/WQ_all.Rds")
+
+#### Process data further ####
+# make datframe for map display and hover data
+WQ_data_locations = WQ_df %>%
+ filter(variable %in% c("geometry", # we don't need this?
+ #"HUC12Name", # Changed for now (bc GTM WQ data does not have that variable) BUT we should also include a station name of some sort
+ "SampleDate", # changed, from StartDate - but also not necessary for locations
+ "Latitude",
+ "Longitude",
+ "data_source")
+ ) %>%
+ #select(c(RowID, variable, value)) %>% # not necessary
+ #distinct(RowID, variable, value) %>% # not necessary
+ pivot_wider(
+ names_from = variable,
+ values_from = value,
+ values_fill = list(value = NA)
+ ) %>%
+ distinct(Latitude, Longitude, data_source, geometry) %>%
+ mutate(
+ Latitude = as.numeric(Latitude),
+ Longitude = as.numeric(Longitude)
+ )
+
+WQ_data_units = WQ_df %>%
+ filter(variable %in% c("ComponentLong", # some will be duplicated because they differ between the 2 sets
+ "Unit", "data_source")
+ ) %>%
+ #select(c(RowID, variable, value)) %>%
+ distinct(RowID, variable, value) %>% # strictly speaking also not necessary
+ pivot_wider(
+ names_from = variable,
+ values_from = value,
+ values_fill = list(value = NA),
+ values_fn = list(value = ~ first(.))
+ ) %>%
+ distinct(ComponentLong, Unit, data_source)
+
+#### Functions ####
+# make dataframe for click plots
+filter_dataframe <- function(df, filter_value = NULL) {
+ if (!is.null(filter_value)) {
+ # Step 1: Identify the relevant RowIDs
+ relevant_row_ids <- df %>%
+ filter(value == filter_value) %>%
+ pull(RowID)
+
+ # Step 2: Filter the entire dataframe to keep only rows with the relevant RowIDs
+ filtered_df <- df %>%
+ filter(RowID %in% relevant_row_ids)
+ } else {
+ # If no filter_value is provided, skip the filtering step
+ filtered_df <- df
+ }
+
+ # Step 3: Create wide dataframe
+ wide_df <- filtered_df %>%
+ pivot_wider(names_from = variable, values_from = value) %>%
+ select(SampleDate, # we could also make these arguments for the function?
+ ComponentLong,
+ Result) %>%
+ pivot_wider(names_from = ComponentLong,
+ values_from = Result,
+ values_fn = list(Result = ~ mean(as.numeric(.), na.rm = TRUE))) %>%
+ mutate(SampleDate = ymd_hms(SampleDate)) %>% #
+ #mutate(SampleDate = str_extract(SampleDate, "[0-9]{4}-[0-9]{2}-[0-9]{2}")) %>%
+ #mutate(SampleDate = ymd(SampleDate)) %>% # these two lines are another option to only get ymd
+ mutate(across(-SampleDate, ~ as.numeric(.))) %>%
+ mutate(SampleDate = as.Date(SampleDate)) %>%
+ group_by(SampleDate) %>%
+ summarize(across(everything(), ~mean(.x, na.rm = TRUE))) %>%
+ select(where(~ n_distinct(.) > 2))
+
+ return(wide_df)
+}
+
+# New function to create the dropdown
+create_dropdown <- function(df, ns) {
+ column_names <- sort(colnames(df)[colnames(df) != "SampleDate"])
+ print(paste("Creating dropdown with choices:", paste(column_names, collapse=", ")))
+
+ selectInput(
+ inputId = ns("column_selector"),
+ label = "Select a Column",
+ choices = column_names,
+ selected = column_names[1]
+ )
+}
+
+# Modified create_plot function
+create_plot <- function(df, units_df, loc_name = "GTMNERR", selected_column) {
+ print(paste("Creating plot for", selected_column))
+ # Initialize the plot with the x-axis
+ fig <- plot_ly(df, x = ~SampleDate)
+
+ # Get the column names except the one for the x-axis
+ column_names <- sort(colnames(df)[colnames(df) != "SampleDate"])
+
+ # Create a named vector for Y-axis titles
+ y_axis_titles <- setNames(units_df$Unit, units_df$ComponentLong)
+
+ # Ensure selected_column is not NULL or empty
+ if (is.null(selected_column) || selected_column == "") {
+ selected_column <- column_names[1]
+ }
+
+ # Loop through each column and add a trace
+ for (i in seq_along(column_names)) {
+ fig <- fig %>%
+ add_trace(y = df[[column_names[i]]], name = column_names[i], type = 'scatter', mode = 'lines',
+ showlegend = FALSE,
+ visible = if (column_names[i] == selected_column) TRUE else FALSE)
+ }
+
+ # Customize the layout
+ fig <- fig %>%
+ layout(xaxis = list(title = 'Date'),
+ yaxis = list(title = y_axis_titles[selected_column]),
+ title = paste("Mean ", selected_column, " for ", loc_name))
+
+ return(fig)
+}
+
+
+#### Run the app ####
+find_directory_of_file("app.R")
+
+# Updated UI in WINPageUI
+WINPageUI <- function(id) {
+ ns <- NS(id)
tagList(
h2("Water Quality Data"),
fluidRow(
- # Map occupies 1st column
- column(width = 7, leafletOutput(ns("map"), height=750)), # make sure to put the input inside ns()
- # histogram occupies rows in the 2nd column
- column(width = 5, plotOutput(ns("distPlot")),
- sliderInput(ns("bins"), "Number of bins:",
- min = 1, max = 50, value = 30)
- )
+ column(width = 7, leafletOutput(ns("map"), height="500px")),
+ column(width = 5, plotlyOutput(ns("plot"), height="500px"))
+ ),
+ fluidRow(
+ column(width = 12, uiOutput(ns("dropdown_ui")))
),
actionButton(inputId = ns("go_back"), label = "Back to Main Page")
)
}
-WQPageServer <- function(id, parentSession) {
- moduleServer(id, function(input, output, session) { # this nested approach is
- # necessary to be able to us the "back" button, otherwise Shiny cannot find
- # the id for "tabs"
+# Updated Server logic in WINPageServer
+WINPageServer <- function(id, parentSession) {
+ moduleServer(id, function(input, output, session) {
ns <- session$ns
-
- # Create the histogram
- output$distPlot <- renderPlot({
- # generate bins based on input$bins from ui.R
- x <- filter(WQ, ComponentShort == "ATEMP") %>%
- select(Result) %>%
- pull()
- x <- as.numeric(x) # stop-gap measure because everything is characters
- bins <- seq(min(x, na.rm = TRUE), max(x, na.rm = TRUE),
- length.out = input$bins + 1
- )
-
- # draw the histogram with the specified number of bins
- hist(x,
- breaks = bins, col = "darkgray", border = "white",
- xlab = "Air temperature (degrees Celsius)",
- main = "Histogram of air temperatures"
- )
+
+ # Reactive value for the selected column
+ selected_column <- reactive({
+ print(paste("Selected column changed to:", input$column_selector))
+ input$column_selector
})
-
+
+ # Reactive value to track popup bubble state
+ popup_visible <- reactiveVal(FALSE)
+
+ # Create the dropdown UI
+ output$dropdown_ui <- renderUI({
+ print("Rendering dropdown UI")
+ df <- filter_dataframe(WQ_df)
+ create_dropdown(df, ns)
+ })
+
+ # Update plot when dropdown selection changes
+ observeEvent(selected_column(), {
+ print(paste("Updating plot for", selected_column()))
+ output$plot <- renderPlotly({
+ df <- filter_dataframe(WQ_df)
+ create_plot(df, units_df = WQ_data_units, selected_column = selected_column())
+ })
+ }, ignoreInit = FALSE)
+
+ # Default plot
+ output$plot <- renderPlotly({
+ df <- filter_dataframe(WQ_df)
+ create_plot(df, units_df = WQ_data_units, selected_column = selected_column())
+ })
+
# Create the map
output$map <- renderLeaflet({
leaflet(options = leafletOptions(minZoom = 9, maxZoom = 18)) %>%
- # setView(lng=-81.347388, lat=30.075, zoom = 11) %>%
- clearBounds() %>% # centers map on all min/max coords
- # Base map
- addTiles() %>% # Add default OpenStreetMap map tiles
- # Polygons, add groups
+ clearBounds() %>%
+ addTiles() %>%
addPolygons(
data = GTMNERR, color = "purple", fill = NA,
weight = 2, opacity = 1, group = "GTMNERR boundaries"
@@ -69,32 +208,72 @@ WQPageServer <- function(id, parentSession) {
color = "white", weight = 2,
bringToFront = TRUE
),
- group = "Counties", popup = ~NAME
+ group = "Counties", popup = ~NAME, layerId = ~NAME
) %>%
- # addMarkers(data = HAB_data_locations,
- # popup = ~paste("Site: ", Site, "
",
- # "County: ", County),
- # group = "HAB") %>%
addMarkers(
data = WQ_data_locations,
- popup = ~ paste(
- "Station: ", site_friendly, "
",
- "Location: ", wbid, "
",
- "Latest year of sampling: ", maxYear, "
"#, #changed from HUC12Name
+ #"Start Date: ", SampleDate, "
"
),
- group = "WQ"
+ group = "WQ",
+ layerId = ~geometry
) %>%
- # # Layers control (turning layers on and off)
addLayersControl(
overlayGroups = c("Counties", "GTMNERR boundaries", "WQ"),
options = layersControlOptions(collapsed = FALSE)
) %>%
addMeasure(primaryLengthUnit = "miles", primaryAreaUnit = "sqmiles")
})
-
+
+ # Observe marker clicks
+ observeEvent(input$map_marker_click, {
+ click <- input$map_marker_click
+ if (!is.null(click)) {
+ clicked_id <- click$id
+ clicked_data <- WQ_data_locations %>%
+ filter(geometry == clicked_id) #GK: I don't think this is a great approach, as
+ # geometry is a specific "thing" for sf objects, so it has specific meaning. And
+ # that is not how we are using it here
+
+ popup_visible(TRUE)
+
+ output$plot <- renderPlotly({
+ df <- filter_dataframe(WQ_df, filter_value = clicked_data$RowID) # Changed from HUC12.Name
+ create_plot(df, units_df = WQ_data_units, loc_name = clicked_data$RowID, selected_column = selected_column())
+ })
+ }
+ })
+
+ # Add observeEvent function for input$map_shape_click
+ observeEvent(input$map_shape_click, {
+ click <- input$map_shape_click
+ if (!is.null(click)) {
+ clicked_id <- click$id
+ clicked_data <- counties_select %>%
+ filter(NAME == clicked_id)
+
+ popup_visible(TRUE)
+
+ output$plot <- renderPlotly({
+ df <- filter_dataframe(WQ_df, filter_value = clicked_data$NAME)
+ create_plot(df, units_df = WQ_data_units, loc_name = clicked_data$NAME, selected_column = selected_column())
+ })
+ }
+ })
+
+ # Observe map clicks to hide the popup
+ observeEvent(input$map_click, {
+ popup_visible(FALSE)
+
+ # Default plot
+ output$plot <- renderPlotly({
+ df <- filter_dataframe(WQ_df)
+ create_plot(df, units_df = WQ_data_units, selected_column = selected_column())
+ })
+ })
+
observeEvent(input$go_back, {
updateTabItems(session = parentSession, inputId = "tabs", selected = "main_page")
})
})
-}
\ No newline at end of file
+}
diff --git a/modules/waterquality2.R b/modules/waterquality2.R
new file mode 100644
index 0000000..813c5bb
--- /dev/null
+++ b/modules/waterquality2.R
@@ -0,0 +1,100 @@
+#### WQ locations data ------------------------------------------------
+WQ_locations <- readRDS("./03_Data_for_app/WQ_locations.Rds")
+WQ_data_locations <- WQ_locations %>%
+ st_as_sf(coords = c("Longitude", "Latitude"), crs = 4326)
+
+#### WQ data ------------------------------------------------
+WQ <- readRDS("./03_Data_for_app/WQ.Rds")
+
+WQPageUI <- function(id) {
+ ns <- NS(id) # This is an important part to add to all sub pages so they use the
+ # correct sessions / ID's that connect the ui and server here
+ tagList(
+ h2("Water Quality Data"),
+ fluidRow(
+ # Map occupies 1st column
+ column(width = 7, leafletOutput(ns("map"), height=750)), # make sure to put the input inside ns()
+ # histogram occupies rows in the 2nd column
+ column(width = 5, plotOutput(ns("distPlot")),
+ sliderInput(ns("bins"), "Number of bins:",
+ min = 1, max = 50, value = 30)
+ )
+ ),
+ actionButton(inputId = ns("go_back"), label = "Back to Main Page")
+ )
+}
+
+WQPageServer <- function(id, parentSession) {
+ moduleServer(id, function(input, output, session) { # this nested approach is
+ # necessary to be able to us the "back" button, otherwise Shiny cannot find
+ # the id for "tabs"
+ ns <- session$ns
+
+ # Create the histogram
+ output$distPlot <- renderPlot({
+ # generate bins based on input$bins from ui.R
+ x <- filter(WQ, ComponentShort == "ATEMP") %>%
+ select(Result) %>%
+ pull()
+ x <- as.numeric(x) # stop-gap measure because everything is characters
+ bins <- seq(min(x, na.rm = TRUE), max(x, na.rm = TRUE),
+ length.out = input$bins + 1
+ )
+
+ # draw the histogram with the specified number of bins
+ hist(x,
+ breaks = bins, col = "darkgray", border = "white",
+ xlab = "Air temperature (degrees Celsius)",
+ main = "Histogram of air temperatures"
+ )
+ })
+
+ # Create the map
+ output$map <- renderLeaflet({
+ leaflet(options = leafletOptions(minZoom = 9, maxZoom = 18)) %>%
+ # setView(lng=-81.347388, lat=30.075, zoom = 11) %>%
+ clearBounds() %>% # centers map on all min/max coords
+ # Base map
+ addTiles() %>% # Add default OpenStreetMap map tiles
+ # Polygons, add groups
+ addPolygons(
+ data = GTMNERR, color = "purple", fill = NA,
+ weight = 2, opacity = 1, group = "GTMNERR boundaries"
+ ) %>%
+ addPolygons(
+ data = counties_select,
+ color = "black", weight = 2, opacity = 1,
+ fill = TRUE, fillColor = "white", fillOpacity = 0.01,
+ highlightOptions = highlightOptions(
+ color = "white", weight = 2,
+ bringToFront = TRUE
+ ),
+ group = "Counties", popup = ~NAME
+ ) %>%
+ # addMarkers(data = HAB_data_locations,
+ # popup = ~paste("Site: ", Site, "
",
+ # "County: ", County),
+ # group = "HAB") %>%
+ addMarkers(
+ data = WQ_data_locations,
+ popup = ~ paste(
+ "Station: ", site_friendly, "
",
+ "Location: ", wbid, "
",
+ "Latest year of sampling: ", maxYear, "
%
+ # # Layers control (turning layers on and off)
+ addLayersControl(
+ overlayGroups = c("Counties", "GTMNERR boundaries", "WQ"),
+ options = layersControlOptions(collapsed = FALSE)
+ ) %>%
+ addMeasure(primaryLengthUnit = "miles", primaryAreaUnit = "sqmiles")
+ })
+
+ observeEvent(input$go_back, {
+ updateTabItems(session = parentSession, inputId = "tabs", selected = "main_page")
+ })
+ })
+}
\ No newline at end of file
diff --git a/modules/win.R b/modules/win.R
deleted file mode 100644
index 53cf4b2..0000000
--- a/modules/win.R
+++ /dev/null
@@ -1,261 +0,0 @@
-# import data for this page
-WIN_df <- readRDS("./03_Data_for_app/WIN.Rds")
-
-#### Process data further ####
-# make datframe for map display and hover data
-WIN_data_locations = WIN_df %>%
- filter(variable %in% c("geometry",
- "HUC12.Name",
- "Start.Date",
- "latitude",
- "longitude")
- ) %>%
- select(c(RowID, variable, value)) %>%
- distinct(RowID, variable, value) %>%
- pivot_wider(
- names_from = variable,
- values_from = value,
- values_fill = list(value = NA)
- ) %>%
- distinct(geometry, HUC12.Name, Start.Date, latitude, longitude) %>%
- mutate(
- latitude = as.numeric(latitude),
- longitude = as.numeric(longitude)
- )
-
-WIN_data_units = WIN_df %>%
- filter(variable %in% c("DEP.Analyte.Name",
- "DEP.Result.Unit")
- ) %>%
- select(c(RowID, variable, value)) %>%
- distinct(RowID, variable, value) %>%
- pivot_wider(
- names_from = variable,
- values_from = value,
- values_fill = list(value = NA),
- values_fn = list(value = ~ first(.))
- ) %>%
- distinct(DEP.Analyte.Name, DEP.Result.Unit)
-
-#### Functions ####
-# make dataframe for click plots
-filter_dataframe <- function(df, filter_value = NULL) {
- if (!is.null(filter_value)) {
- # Step 1: Identify the relevant RowIDs
- relevant_row_ids <- df %>%
- filter(value == filter_value) %>%
- pull(RowID)
-
- # Step 2: Filter the entire dataframe to keep only rows with the relevant RowIDs
- filtered_df <- df %>%
- filter(RowID %in% relevant_row_ids)
- } else {
- # If no filter_value is provided, skip the filtering step
- filtered_df <- df
- }
-
- # Step 3: Create wide dataframe
- wide_df <- filtered_df %>%
- pivot_wider(names_from = variable, values_from = value) %>%
- select(Activity.Start.Date.Time,
- DEP.Analyte.Name,
- Org.Result.Value) %>%
- pivot_wider(names_from = DEP.Analyte.Name,
- values_from = Org.Result.Value,
- values_fn = list(Org.Result.Value = ~ mean(as.numeric(.), na.rm = TRUE))) %>%
- mutate(Activity.Start.Date.Time = ymd_hms(Activity.Start.Date.Time)) %>%
- mutate(across(-Activity.Start.Date.Time, ~ as.numeric(.))) %>%
- mutate(Activity.Start.Date.Time = as.Date(Activity.Start.Date.Time)) %>%
- group_by(Activity.Start.Date.Time) %>%
- summarize(across(everything(), ~mean(.x, na.rm = TRUE))) %>%
- select(where(~ n_distinct(.) > 2))
-
- return(wide_df)
-}
-
-# New function to create the dropdown
-create_dropdown <- function(df, ns) {
- column_names <- sort(colnames(df)[colnames(df) != "Activity.Start.Date.Time"])
- print(paste("Creating dropdown with choices:", paste(column_names, collapse=", ")))
-
- selectInput(
- inputId = ns("column_selector"),
- label = "Select a Column",
- choices = column_names,
- selected = column_names[1]
- )
-}
-
-# Modified create_plot function
-create_plot <- function(df, units_df, loc_name = "GTMNERR", selected_column) {
- print(paste("Creating plot for", selected_column))
- # Initialize the plot with the x-axis
- fig <- plot_ly(df, x = ~Activity.Start.Date.Time)
-
- # Get the column names except the one for the x-axis
- column_names <- sort(colnames(df)[colnames(df) != "Activity.Start.Date.Time"])
-
- # Create a named vector for Y-axis titles
- y_axis_titles <- setNames(units_df$DEP.Result.Unit, units_df$DEP.Analyte.Name)
-
- # Ensure selected_column is not NULL or empty
- if (is.null(selected_column) || selected_column == "") {
- selected_column <- column_names[1]
- }
-
- # Loop through each column and add a trace
- for (i in seq_along(column_names)) {
- fig <- fig %>%
- add_trace(y = df[[column_names[i]]], name = column_names[i], type = 'scatter', mode = 'lines',
- visible = if (column_names[i] == selected_column) TRUE else FALSE)
- }
-
- # Customize the layout
- fig <- fig %>%
- layout(xaxis = list(title = 'Date'),
- yaxis = list(title = y_axis_titles[selected_column]),
- title = paste("Mean ", selected_column, " for ", loc_name))
-
- return(fig)
-}
-
-
-#### Run the app ####
-find_directory_of_file("app.R")
-
-# Updated UI in WINPageUI
-WINPageUI <- function(id) {
- ns <- NS(id)
- tagList(
- h2("Water Information Network"),
- fluidRow(
- column(width = 7, leafletOutput(ns("map"), height="500px")),
- column(width = 5, plotlyOutput(ns("plot"), height="500px"))
- ),
- fluidRow(
- column(width = 12, uiOutput(ns("dropdown_ui")))
- ),
- actionButton(inputId = ns("go_back"), label = "Back to Main Page")
- )
-}
-
-# Updated Server logic in WINPageServer
-WINPageServer <- function(id, parentSession) {
- moduleServer(id, function(input, output, session) {
- ns <- session$ns
-
- # Reactive value for the selected column
- selected_column <- reactive({
- print(paste("Selected column changed to:", input$column_selector))
- input$column_selector
- })
-
- # Reactive value to track popup bubble state
- popup_visible <- reactiveVal(FALSE)
-
- # Create the dropdown UI
- output$dropdown_ui <- renderUI({
- print("Rendering dropdown UI")
- df <- filter_dataframe(WIN_df)
- create_dropdown(df, ns)
- })
-
- # Update plot when dropdown selection changes
- observeEvent(selected_column(), {
- print(paste("Updating plot for", selected_column()))
- output$plot <- renderPlotly({
- df <- filter_dataframe(WIN_df)
- create_plot(df, units_df = WIN_data_units, selected_column = selected_column())
- })
- }, ignoreInit = FALSE)
-
- # Default plot
- output$plot <- renderPlotly({
- df <- filter_dataframe(WIN_df)
- create_plot(df, units_df = WIN_data_units, selected_column = selected_column())
- })
-
- # Create the map
- output$map <- renderLeaflet({
- leaflet(options = leafletOptions(minZoom = 9, maxZoom = 18)) %>%
- clearBounds() %>%
- addTiles() %>%
- addPolygons(
- data = GTMNERR, color = "purple", fill = NA,
- weight = 2, opacity = 1, group = "GTMNERR boundaries"
- ) %>%
- addPolygons(
- data = counties_select,
- color = "black", weight = 2, opacity = 1,
- fill = TRUE, fillColor = "white", fillOpacity = 0.01,
- highlightOptions = highlightOptions(
- color = "white", weight = 2,
- bringToFront = TRUE
- ),
- group = "Counties", popup = ~NAME, layerId = ~NAME
- ) %>%
- addMarkers(
- data = WIN_data_locations,
- popup = ~ paste("Station Name: ", HUC12.Name, "
",
- "Start Date: ", Start.Date, "
"
- ),
- group = "WIN",
- layerId = ~geometry
- ) %>%
- addLayersControl(
- overlayGroups = c("Counties", "GTMNERR boundaries", "WIN"),
- options = layersControlOptions(collapsed = FALSE)
- ) %>%
- addMeasure(primaryLengthUnit = "miles", primaryAreaUnit = "sqmiles")
- })
-
- # Observe marker clicks
- observeEvent(input$map_marker_click, {
- click <- input$map_marker_click
- if (!is.null(click)) {
- clicked_id <- click$id
- clicked_data <- WIN_data_locations %>%
- filter(geometry == clicked_id)
-
- popup_visible(TRUE)
-
- output$plot <- renderPlotly({
- df <- filter_dataframe(WIN_df, filter_value = clicked_data$HUC12.Name)
- create_plot(df, units_df = WIN_data_units, loc_name = clicked_data$HUC12.Name, selected_column = selected_column())
- })
- }
- })
-
- # Add observeEvent function for input$map_shape_click
- observeEvent(input$map_shape_click, {
- click <- input$map_shape_click
- if (!is.null(click)) {
- clicked_id <- click$id
- clicked_data <- counties_select %>%
- filter(NAME == clicked_id)
-
- popup_visible(TRUE)
-
- output$plot <- renderPlotly({
- df <- filter_dataframe(WIN_df, filter_value = clicked_data$NAME)
- create_plot(df, units_df = WIN_data_units, loc_name = clicked_data$NAME, selected_column = selected_column())
- })
- }
- })
-
- # Observe map clicks to hide the popup
- observeEvent(input$map_click, {
- popup_visible(FALSE)
-
- # Default plot
- output$plot <- renderPlotly({
- df <- filter_dataframe(WIN_df)
- create_plot(df, units_df = WIN_data_units, selected_column = selected_column())
- })
- })
-
- observeEvent(input$go_back, {
- updateTabItems(session = parentSession, inputId = "tabs", selected = "main_page")
- })
- })
-}