R/run_app.R

Defines functions marineApp

Documented in marineApp

#' @title Run the marineApp Application
#'
#' @export

marineApp <- function(...) {
  # User interface
  ui <- shiny.semantic::semanticPage(
    # Adding css
    shiny::tags$head(shiny::includeCSS(path = "inst/app/www/styles.css")),

    # Presenting some informations at the very beggining
    shiny::uiOutput("start_modal"),

    # Creating a grid to display the app
    shiny.semantic::grid(
      grid_template = shiny.semantic::grid_template(
        default = list(
          areas = rbind(
            c("header", "map"),
            c("stats", "map"),
            c("author", "map")
          ),
          cols_width = c("400px", "1fr"),
          rows_height = c("50px", "auto", "50px")
        )
      ),
      # Defining area layouts
      area_styles = list(
        header = "margin: 15px;",
        stats = "margin: 15px; padding-top: 15px;",
        author = "position: fixed; bottom: 0",
        map = "margin: 15px 15px 15px 0px"),
      # Header
      header = shiny::div(
        class = "ui raised segment inverted",
        shiny::h2(class = "title", "Marine App"),
        style = "background-color: #212122"
      ),
      # Stats
      stats = shiny::div(
        class = "ui raised segment inverted",
        select_vessel_ui(id = "name", marine_stats = marine_stats),
        shiny::br(),
        shiny::uiOutput(outputId = "stats"),
        style = "background-color: #212122"
      ),
      # Author
      author = shiny.semantic::card(
        style = "border-radius: 0; width: 400px; background: #efefef",
        shiny::div(
          class = "content",
          shiny::img(class = "right floated mini ui image", src = "https://avatars.githubusercontent.com/u/13513569?s=96&v=4"),
          shiny::div(
            class = "header",
            "Douglas Mesquita",
            shiny::tags$a(
              href = "https://github.com/DouglasMesquita",
              shiny::icon(name = "github", class = "my_icon"),
              target = "_blank",
              style = "padding-left: 15px"
            ),
            shiny::tags$a(
              href = "https://www.linkedin.com/in/douglas-mesquita/",
              shiny::icon(name = "linkedin", class = "my_icon"),
              target = "_blank"
            ),
            shiny::tags$a(
              href = "https://www.require-r.com/",
              shiny::icon(name = "globe", class = "my_icon"),
              target = "_blank"
            )
          ),
          shiny::div(class = "meta", "Statistician/Data scientist")
        )
      ),
      map = leaflet::leafletOutput(outputId = "map")
    )
  )

  # Server functions
  server <- function(input, output, session) {
    # Welcome modal
    output$start_modal <- renderUI({
      shiny.semantic::create_modal(
        shiny.semantic::modal(
          id = "start-modal",
          title = "Marine app",
          header = shiny::h2(class = "ui header", shiny::icon("ship"), shiny::div(class = "content", "Before you start"), style = "font-weight: 100"),
          content = shiny.semantic::grid(
            grid_template = shiny.semantic::grid_template(
              default = list(
                areas = rbind(c("photo", "text")),
                cols_width = c("50%", "50%")
              ),
              mobile = list(
                areas = rbind(c("photo"), c("text")),
                cols_width = c("100%"),
                rows_height = c("50%", "50%")
              )
            ),
            container_style = "grid-gap: 20px",
            area_styles = list(text = "padding-right: 20px"),
            photo = shiny::tags$img(
              src = "https://lh3.googleusercontent.com/proxy/cdLYKzVhZyhQWwaiN0v1bDyww71UCSndxLcABtn96mzDWDm95dAMvTL1-uNordijIT6dIFGdD9xdnSIz5BJmi3V7xITP-teDq-Miq07w-YPNVfo",
              style = "max-height: 400px; max-width: 100%;"
            ),
            text = shiny::HTML(
              "<span>In this app you will find several vessel's information. Here is how it works:</span>
              <br><br>
              <li>Select a vessel type from the dropdown menu</li>
              <li>Select a specific vessel from the dropdown menu</li>
              <li>Observe its statistics and trajectory</li>
              <br>
              <h2>Easy peasy!</h2>
              <br>
              <span>* Notice that not all the vessel's photos are available.</span>
              "
            )
          )
        ))
    })

    # Dropdown buttons to select a vessel
    select_vessel_server(id = "name", marine_stats = marine_stats)

    # Vessel data reactive
    vessel_data <- shiny::eventReactive(c(input$vessel_type, input$vessel_name), {
      type_sel <- input$`name-vessel_type`
      name_sel <- input$`vessel_name`

      vessel_stats <- marine_stats %>%
        dplyr::filter(vessel_type == type_sel, vessel_name == name_sel) %>%
        dplyr::slice(1) # Just in case

      vessel <- marine %>%
        dplyr::filter(vessel_type == type_sel, vessel_name == name_sel)

      return(list(vessel_stats = vessel_stats, vessel = vessel))
    })

    # Output stats
    output$stats <- shiny::renderUI({
      marine_stats <- vessel_data()$vessel_stats

      vessel_stats(marine_stats = marine_stats)
    })

    # Output map
    output$map <- leaflet::renderLeaflet({
      # Getting the data
      marine_list <- vessel_data()
      marine_stats <- marine_list$vessel_stats

      # Auxiliar datasets
      from <- marine_stats$port
      to <- ifelse(test = is.na(marine_stats$destination), yes = "missing", no = marine_stats$destination)

      marine_coords <- marine_list$vessel %>%
        dplyr::mutate(destination = dplyr::if_else(condition = is.na(destination), true = "missing", false = destination)) %>%
        dplyr::filter(port == from, destination == to) %>%
        dplyr::group_by(vessel_name) %>%
        dplyr::arrange(datetime) %>%
        dplyr::ungroup() %>%
        dplyr::select(lat, lon) %>%
        unique()

      marine_aux <- data.frame(
        lat_start = marine_coords$lat[1],
        lat_end = tail(x = marine_coords$lat, n = 1),
        lon_start = marine_coords$lon[1],
        lon_end = tail(x = marine_coords$lon, n = 1)
      )

      leaflet::leaflet() %>%
        # Dashed lines for the journey
        leaflet::addPolylines(
          data = marine_coords,
          lng = ~lon,
          lat = ~lat,
          weight = 1,
          dashArray = 3,
          color = "white",
        ) %>%
        # Start point
        leaflet::addCircleMarkers(
          data = marine_aux, lat = ~lat_start, lng = ~lon_start,
          color = "#aad3df", fillOpacity = 0.65, radius = 8, weight = 1,
          label = "Start point"
        ) %>%
        # End point
        leaflet::addCircleMarkers(
          data = marine_aux, lat = ~lat_end, lng = ~lon_end,
          color = "#aadfac", fillOpacity = 0.65, radius = 8, weight = 1,
          label = "End point"
        ) %>%
        # Dashed lines for the longest interval without messages
        leaflet::addPolylines(
          lng = c(marine_stats$lon, marine_stats$lon_lag1),
          lat = c(marine_stats$lat, marine_stats$lat_lag1),
          weight = 3,
          dashArray = 0,
          color = "red",
        ) %>%
        # Start point with biggest distance without any observation
        leaflet::addCircleMarkers(
          data = marine_stats, lat = ~lat_lag1, lng = ~lon_lag1,
          color = "red", fillOpacity = 0.65, radius = 3, weight = 1,
          label = shiny::HTML(sprintf("<b>Start point</b><br>%s meters without a message", round(marine_stats$dist, 2)))
        ) %>%
        # End point with biggest distance without any observation
        leaflet::addCircleMarkers(
          data = marine_stats, lat = ~lat, lng = ~lon,
          color = "red", fillOpacity = 0.65, radius = 3, weight = 1,
          label = shiny::HTML(sprintf("<b>End point</b><br>%s meters without a message", round(marine_stats$dist, 2)))
        ) %>%
        # Adding minimap to make easy to understand the geographic location
        leaflet::addMiniMap() %>%
        # Adding a dark theme
        leaflet::addProviderTiles(
          provider = leaflet::providers$CartoDB.DarkMatter,
          options = leaflet::providerTileOptions(noWrap = T)
        ) %>%
        add_custom_legend(
          colors = c("#aad3df", "#aadfac", "red"),
          labels = c("Journey's start", "Journey's end", "Longest period without messages"),
          sizes = c(10, 10, 10),
          opacity = 0.65
        )
    })
  }

  # Running shiny
  shiny::shinyApp(ui, server)
}
DouglasMesquita/marineApp documentation built on Dec. 17, 2021, 5:29 p.m.