cjerzak's picture
Update app.R
f02e31c verified
raw
history blame
3.37 kB
# =============================
# Global options & libraries
# =============================
library(shiny)
library(shinydashboard) # or bslib / thematic, if desired
library(dplyr)
library(readr)
library(sf)
library(cartogram)
library(ggplot2)
library(rnaturalearth)
library(rnaturalearthdata)
# =============================
# UI
# =============================
ui <- dashboardPage(
dashboardHeader(title = "Country Representation Rankings"),
dashboardSidebar(
sidebarMenu(
menuItem("Cartogram", tabName = "cartogramTab", icon = icon("globe"))
),
# User input: which representation index to display
selectInput(
inputId = "indexChoice",
label = "Select Representation Index:",
choices = c("Overall", "Representation Gap", "Ethnicity",
"Gender", "Religion", "Language"),
selected = "Overall"
)
),
dashboardBody(
tabItems(
tabItem(
tabName = "cartogramTab",
fluidRow(
box(
width = 12,
plotOutput("cartogramPlot", height = "600px")
)
)
)
)
)
)
# =============================
# SERVER
# =============================
server <- function(input, output, session) {
# ---- Read CSV data ----
# Modify the path to your CSV as needed
rankings_data <- reactive({
read_csv("CountryRepresentationRankings.csv") %>%
# Make sure "Country" and "Population" columns are present:
# e.g., rename columns if your CSV differs
rename(name = Country) # rename to match natural earth "name" field
})
# ---- Read/prepare world map shapefile ----
world_sf <- reactive({
# Download a simple polygons set
ne_countries(scale = "medium", returnclass = "sf") %>%
select(name, iso_a3, geometry) # keep only relevant columns
})
# ---- Join data and create cartogram ----
cartogram_sf <- reactive({
# Join your data on "name"
merged_sf <- world_sf() %>%
left_join(rankings_data(), by = "name")
# cartogram_cont scales polygon area proportionally to your "Population" column
# If you do NOT have a "Population" column, you could use "pop_est" from
# the natural earth data or from your CSV if provided.
cartogram_cont(merged_sf, weight = "Population", prepare = TRUE)
})
# ---- Plot output ----
output$cartogramPlot <- renderPlot({
req(input$indexChoice)
# The user’s chosen index to display
index_col <- input$indexChoice
# Prepare the cartogram for plotting
plot_data <- cartogram_sf()
# Basic ggplot: color fill by the chosen index
ggplot(plot_data) +
geom_sf(aes_string(fill = index_col), color = "grey20", size = 0.1) +
scale_fill_viridis_c(option = "D", na.value = "white") +
theme_minimal(base_size = 14) +
labs(
fill = paste(index_col, "Index"),
title = "Country Representation Rankings",
subtitle = "Cartogram sized by Population, colored by selected Index",
caption = "Source: Global Leadership Project (GLP)"
) +
theme(
plot.title = element_text(face = "bold"),
axis.text = element_blank(),
axis.ticks = element_blank()
)
})
}
# =============================
# Launch the Shiny App
# =============================
shinyApp(ui = ui, server = server)