diff --git a/app.R b/app.R index 39efe18..1d38a62 100644 --- a/app.R +++ b/app.R @@ -1,40 +1,43 @@ -# 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 and Shellfish Data", tabName = "shellfish", icon = icon("fish", lib="font-awesome")), + menuItem("Terrestrial Animal Data", tabName = "animal", icon = icon("paw", 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 ea00e84..14d5afc 100644 --- a/modules/main_page.R +++ b/modules/main_page.R @@ -18,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) %>% @@ -30,24 +30,28 @@ 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"), #, "blue", "green", "purple" - domain = datasets_location$type) +color_palette <- colorFactor(palette = c("red", "goldenrod1"), #, "blue", "green" + domain = datasets_location$dataset) #### HAB locations data ------------------------------------------------ # Add this at some point so there is another dataset that shows up in the dropdown @@ -94,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 @@ -142,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 409747b..0000000 --- a/modules/win.R +++ /dev/null @@ -1,271 +0,0 @@ -######################################################################## -########## NERRS Science Transfer project - GTMNERR ############# -######################################################################## - -# Geraldine Klarenberg, PhD -# Email: gklarenberg@ufl.edu -# Christopher Marais -# Email: -# Last updated: 12 August 2024 - -# 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", - "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) - ) - -WQ_data_units = WQ_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(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)) %>% - 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 = WQ_data_locations, - popup = ~ paste("Station Name: ", HUC12.Name, "
", - "Start Date: ", Start.Date, "
" - ), - group = "WQ", - layerId = ~geometry - ) %>% - 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) - - popup_visible(TRUE) - - output$plot <- renderPlotly({ - df <- filter_dataframe(WQ_df, filter_value = clicked_data$HUC12.Name) - create_plot(df, units_df = WQ_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(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") - }) - }) -}