File size: 3,272 Bytes
42b4218
0dbfc34
42b4218
f02e31c
 
 
 
 
 
 
42b4218
8aa102f
f02e31c
 
 
 
 
 
 
 
0dbfc34
f02e31c
 
 
 
42b4218
f02e31c
 
 
 
 
 
 
 
 
 
 
 
 
 
8aa102f
 
 
0dbfc34
 
f02e31c
 
 
0dbfc34
2acecda
42b4218
f02e31c
 
42b4218
 
8aa102f
 
f02e31c
 
 
42b4218
 
f02e31c
 
42b4218
f02e31c
42b4218
f02e31c
42b4218
 
8aa102f
42b4218
 
 
 
 
 
 
 
8aa102f
2acecda
f02e31c
 
 
8aa102f
f02e31c
 
8aa102f
f02e31c
 
 
 
8aa102f
f02e31c
 
d2be2d3
42b4218
8aa102f
f02e31c
 
 
 
 
8aa102f
0dbfc34
 
f02e31c
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
options(error = NULL)
library(shiny)
library(shinydashboard)
library(dplyr)
library(readr)
library(sf)
library(cartogram)
library(ggplot2)
library(rnaturalearth)
library(rnaturalearthdata)
library(countrycode)   

# =============================
#         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", "RepresentationGap", "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 and create ISO3 codes ----
  rankings_data <- reactive({
    read_csv("CountryRepresentationRankings.csv") %>%
      # Use countrycode to convert the country names to ISO3 codes
      mutate(iso_a3 = countrycode(Country, origin = "country.name", destination = "iso3c"))
  })
  
  # ---- Read/prepare world map shapefile ----
  world_sf <- reactive({
    ne_countries(scale = "medium", returnclass = "sf") %>%
      select(name, iso_a3, pop_est, geometry) %>%  # includes iso_a3 for merging
      st_transform(crs = "ESRI:54009")             # projected coordinate system
  })
  
  # ---- Create cartogram ----
  cartogram_sf <- reactive({
    # Merge your CSV data (for coloring) with Natural Earth polygons via ISO3
    merged_sf <- world_sf() %>%
      left_join(rankings_data(), by = "iso_a3")
    merged_sf <- merged_sf[!is.na(merged_sf$Overall),]
    
    # You can choose which variable to use for the cartogram distortion.
    # If you want to size by pop_est, use weight = "pop_est"
    #cartogram_cont(
      #merged_sf,
      #weight = "pop_est",
      #prepare = TRUE)
    #return( cartogram_dorling( merged_sf, weight = "pop_est" ))  
    return( merged_sf )
  })
  
  # ---- Plot output ----
  output$cartogramPlot <- renderPlot({
    req(input$indexChoice)
    
    index_col <- input$indexChoice
    plot_data <- cartogram_sf()
    
    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 = "Map Colored by Selected Representation Index",
        caption = "Source: Global Leadership Project (GLP) & Natural Earth"
      ) +
      theme(
        plot.title = element_text(face = "bold"),
        axis.text = element_blank(),
        axis.ticks = element_blank()
      )
  })
}

# =============================
#   Launch the Shiny App
# =============================
shinyApp(ui = ui, server = server)