#' @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)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.