cjerzak commited on
Commit
20b5007
·
verified ·
1 Parent(s): 8061733

Update app.R

Browse files
Files changed (1) hide show
  1. app.R +50 -42
app.R CHANGED
@@ -10,26 +10,19 @@ library(rnaturalearth)
10
  library(rnaturalearthdata)
11
  library(countrycode)
12
  library(ggplot2)
13
- library(ggiraph) # For interactive hover tooltips
14
- #library(extrafont)
15
- #font_import() # run
16
- #loadfonts() # load the fonts into R session
17
 
18
  # =============================
19
  # UI
20
  # =============================
21
  ui <- dashboardPage(
22
-
23
- # Use black skin for the dashboard
24
  skin = "black",
25
-
26
  dashboardHeader(
27
  title = span(
28
  style = "font-weight: 600; font-size: 18px;",
29
  "Country Representation"
30
  )
31
  ),
32
-
33
  dashboardSidebar(
34
  sidebarMenu(
35
  menuItem("Map Type", tabName = "cartogramTab", icon = icon("globe"))
@@ -45,9 +38,7 @@ ui <- dashboardPage(
45
  )
46
  )
47
  ),
48
-
49
  dashboardBody(
50
- # Bring in the OCR A Extended font from Google Fonts
51
  tags$head(
52
  tags$link(
53
  href = "https://fonts.googleapis.com/css2?family=OCR+A+Extended&display=swap",
@@ -118,7 +109,6 @@ ui <- dashboardPage(
118
  }
119
  "))
120
  ),
121
-
122
  tabItems(
123
  tabItem(
124
  tabName = "cartogramTab",
@@ -127,12 +117,20 @@ ui <- dashboardPage(
127
  width = 12,
128
  title = strong("Global Leadership Project (GLP)"),
129
  solidHeader = TRUE,
130
- # Use girafeOutput instead of plotOutput
131
  div(
132
- style = "height: 80vh; padding: 10px;",
133
  girafeOutput("cartogramPlot", width = "100%", height = "100%")
134
  )
135
  )
 
 
 
 
 
 
 
 
 
136
  )
137
  )
138
  )
@@ -144,23 +142,6 @@ ui <- dashboardPage(
144
  # =============================
145
  server <- function(input, output, session) {
146
 
147
- # Reactive value to store the currently clicked country
148
- clicked_country <- reactiveVal(NULL)
149
-
150
- # Observe clicks on the map
151
- observeEvent(input$cartogramPlot_selected, {
152
- selected_id <- input$cartogramPlot_selected
153
- current_clicked <- clicked_country()
154
-
155
- if (identical(selected_id, current_clicked)) {
156
- # Unclick: set clicked_country to NULL
157
- clicked_country(NULL)
158
- } else {
159
- # Click new country: update clicked_country
160
- clicked_country(selected_id)
161
- }
162
- }, ignoreNULL = FALSE)
163
-
164
  # 1. Custom matches for countries not recognized by default in 'countrycode'
165
  custom_iso_matches <- c("Kosovo" = "XKX",
166
  "Somaliland" = "SOM") # or any valid code you prefer
@@ -187,7 +168,6 @@ server <- function(input, output, session) {
187
  cartogram_sf <- reactive({
188
  merged_sf <- world_sf() %>%
189
  left_join(rankings_data(), by = "iso_a3")
190
- # Filter out rows with missing 'Overall', if you want to exclude them
191
  merged_sf <- merged_sf[!is.na(merged_sf$Overall),]
192
  merged_sf
193
  })
@@ -198,9 +178,8 @@ server <- function(input, output, session) {
198
 
199
  plot_data <- cartogram_sf()
200
  index_col <- input$indexChoice
201
- selected_country_id <- clicked_country()
202
 
203
- # Build a tooltip string: customize to your preference
204
  plot_data$tooltip_text <- paste0(
205
  "<b>Country:</b> ", plot_data$Country, "<br/>",
206
  "<b>Overall:</b> ", ifelse(!is.na(plot_data$Overall), plot_data$Overall, "N/A"), "<br/>",
@@ -211,21 +190,18 @@ server <- function(input, output, session) {
211
  "<b>Language:</b> ", ifelse(!is.na(plot_data$Language), plot_data$Language, "N/A")
212
  )
213
 
214
- # Use geom_sf_interactive with aes() + get() instead of aes_string()
215
  p <- ggplot(plot_data) +
216
  geom_sf_interactive(
217
  aes(
218
  fill = get(index_col),
219
  tooltip = tooltip_text,
220
- data_id = iso_a3
221
  ),
222
  color = "grey20",
223
  size = 0.1
224
  ) +
225
  scale_fill_viridis_c(option = "D", na.value = "white") +
226
  coord_sf(expand = FALSE) +
227
- # Use a generic base_family to avoid font errors
228
- #theme_void(base_size = 14, base_family = "Courier New") +
229
  theme_void(base_size = 14, base_family = "sans") +
230
  labs(
231
  fill = paste(index_col, "Index"),
@@ -242,22 +218,54 @@ server <- function(input, output, session) {
242
  legend.key.width = unit(2, "cm")
243
  )
244
 
245
- # Wrap the ggplot in a girafe object, including tooltip styling and click handling
246
  girafe(
247
  ggobj = p,
248
  width_svg = 10,
249
  height_svg = 6,
250
  options = list(
251
  opts_tooltip(
252
- css = "background-color: white;
253
- font-family: 'OCR A Extended', monospace;
254
  color: black;"
255
  ),
256
- opts_selection(type = "single", selected = selected_country_id),
257
- opts_zoom(max = 5)
258
  )
259
  )
260
  })
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
261
  }
262
 
263
  # =============================
 
10
  library(rnaturalearthdata)
11
  library(countrycode)
12
  library(ggplot2)
13
+ library(ggiraph) # For interactive hover tooltips and selections
 
 
 
14
 
15
  # =============================
16
  # UI
17
  # =============================
18
  ui <- dashboardPage(
 
 
19
  skin = "black",
 
20
  dashboardHeader(
21
  title = span(
22
  style = "font-weight: 600; font-size: 18px;",
23
  "Country Representation"
24
  )
25
  ),
 
26
  dashboardSidebar(
27
  sidebarMenu(
28
  menuItem("Map Type", tabName = "cartogramTab", icon = icon("globe"))
 
38
  )
39
  )
40
  ),
 
41
  dashboardBody(
 
42
  tags$head(
43
  tags$link(
44
  href = "https://fonts.googleapis.com/css2?family=OCR+A+Extended&display=swap",
 
109
  }
110
  "))
111
  ),
 
112
  tabItems(
113
  tabItem(
114
  tabName = "cartogramTab",
 
117
  width = 12,
118
  title = strong("Global Leadership Project (GLP)"),
119
  solidHeader = TRUE,
 
120
  div(
121
+ style = "height: 70vh; padding: 10px;", # Adjusted height to make space
122
  girafeOutput("cartogramPlot", width = "100%", height = "100%")
123
  )
124
  )
125
+ ),
126
+ # New box for displaying selected country data
127
+ fluidRow(
128
+ box(
129
+ width = 12,
130
+ title = strong("Selected Country Data"),
131
+ solidHeader = TRUE,
132
+ uiOutput("selectedCountryData")
133
+ )
134
  )
135
  )
136
  )
 
142
  # =============================
143
  server <- function(input, output, session) {
144
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
145
  # 1. Custom matches for countries not recognized by default in 'countrycode'
146
  custom_iso_matches <- c("Kosovo" = "XKX",
147
  "Somaliland" = "SOM") # or any valid code you prefer
 
168
  cartogram_sf <- reactive({
169
  merged_sf <- world_sf() %>%
170
  left_join(rankings_data(), by = "iso_a3")
 
171
  merged_sf <- merged_sf[!is.na(merged_sf$Overall),]
172
  merged_sf
173
  })
 
178
 
179
  plot_data <- cartogram_sf()
180
  index_col <- input$indexChoice
 
181
 
182
+ # Build a tooltip string (same as data to display on click)
183
  plot_data$tooltip_text <- paste0(
184
  "<b>Country:</b> ", plot_data$Country, "<br/>",
185
  "<b>Overall:</b> ", ifelse(!is.na(plot_data$Overall), plot_data$Overall, "N/A"), "<br/>",
 
190
  "<b>Language:</b> ", ifelse(!is.na(plot_data$Language), plot_data$Language, "N/A")
191
  )
192
 
 
193
  p <- ggplot(plot_data) +
194
  geom_sf_interactive(
195
  aes(
196
  fill = get(index_col),
197
  tooltip = tooltip_text,
198
+ data_id = iso_a3 # Enable selection with unique identifier
199
  ),
200
  color = "grey20",
201
  size = 0.1
202
  ) +
203
  scale_fill_viridis_c(option = "D", na.value = "white") +
204
  coord_sf(expand = FALSE) +
 
 
205
  theme_void(base_size = 14, base_family = "sans") +
206
  labs(
207
  fill = paste(index_col, "Index"),
 
218
  legend.key.width = unit(2, "cm")
219
  )
220
 
 
221
  girafe(
222
  ggobj = p,
223
  width_svg = 10,
224
  height_svg = 6,
225
  options = list(
226
  opts_tooltip(
227
+ css = "background-color: white;
228
+ font-family: 'OCR A Extended', monospace;
229
  color: black;"
230
  ),
231
+ opts_selection(type = "single") # Single selection: one country at a time
 
232
  )
233
  )
234
  })
235
+
236
+ # Reactive to track the selected country's ISO code
237
+ selected_iso <- reactive({
238
+ input$cartogramPlot_selected # Returns the data_id of the selected country or NULL
239
+ })
240
+
241
+ # Reactive to fetch the selected country's data
242
+ selected_data <- reactive({
243
+ if (is.null(selected_iso())) {
244
+ return(NULL)
245
+ } else {
246
+ rankings_data() %>%
247
+ filter(iso_a3 == selected_iso())
248
+ }
249
+ })
250
+
251
+ # Render the selected country data below the map
252
+ output$selectedCountryData <- renderUI({
253
+ if (is.null(selected_data())) {
254
+ HTML("<p>Select a country by clicking on the map.</p>")
255
+ } else {
256
+ data <- selected_data()
257
+ html_content <- paste0(
258
+ "<b>Country:</b> ", data$Country, "<br/>",
259
+ "<b>Overall:</b> ", ifelse(is.na(data$Overall), "N/A", data$Overall), "<br/>",
260
+ "<b>Representation Gap:</b> ", ifelse(is.na(data$RepresentationGap), "N/A", data$RepresentationGap), "<br/>",
261
+ "<b>Ethnicity:</b> ", ifelse(is.na(data$Ethnicity), "N/A", data$Ethnicity), "<br/>",
262
+ "<b>Gender:</b> ", ifelse(is.na(data$Gender), "N/A", data$Gender), "<br/>",
263
+ "<b>Religion:</b> ", ifelse(is.na(data$Religion), "N/A", data$Religion), "<br/>",
264
+ "<b>Language:</b> ", ifelse(is.na(data$Language), "N/A", data$Language)
265
+ )
266
+ HTML(html_content)
267
+ }
268
+ })
269
  }
270
 
271
  # =============================