@@ -141,47 +141,67 @@ format_date_label <- function(d) {
141141 paste0(format(d , " %d %b" ), " \n " , format(d , " %Y" ))
142142}
143143
144- start_v1_label <- format_date_label(min(v1_dates ))
145- latest_v1_label <- format_date_label(max(v1_dates ))
146- start_v2_label <- format_date_label(min(v2_dates ))
147- latest_v2_label <- format_date_label(max(v2_dates ))
144+ date_extent <- function (dates ) {
145+ dates <- dates [! is.na(dates )]
146+ if (length(dates ) == 0 ) {
147+ return (list (start = as.Date(NA ), latest = as.Date(NA )))
148+ }
149+
150+ list (start = min(dates ), latest = max(dates ))
151+ }
152+
153+ v1_extent <- date_extent(v1_dates )
154+ v2_extent <- date_extent(v2_dates )
155+
156+ start_v1_label <- format_date_label(v1_extent $ start )
157+ latest_v1_label <- format_date_label(v1_extent $ latest )
158+ start_v2_label <- format_date_label(v2_extent $ start )
159+ latest_v2_label <- format_date_label(v2_extent $ latest )
148160
149161# Write Shields.io JSON for dynamic badges
150162output_dir <- dirname(output_path )
151- if (length(v1_dates ) > 0 ) {
152- v1_json <- list (
153- schemaVersion = 1 ,
154- label = " latest v1 data" ,
155- message = as.character(max(v1_dates )),
156- color = " D35252" # Dusty coral red
157- )
158- jsonlite :: write_json(v1_json , file.path(output_dir , " latest_v1.json" ), auto_unbox = TRUE )
159- }
160- if (length(v2_dates ) > 0 ) {
161- v2_json <- list (
163+
164+ write_latest_json <- function (latest_date , path , label , color ) {
165+ available <- ! is.na(latest_date )
166+ json <- list (
162167 schemaVersion = 1 ,
163- label = " latest v2 data " ,
164- message = as.character(max( v2_dates )) ,
165- color = " 9E1B1B " # Deep crimson red
168+ label = label ,
169+ message = if ( available ) as.character(latest_date ) else " unavailable " ,
170+ color = if ( available ) color else " lightgrey "
166171 )
167- jsonlite :: write_json(v2_json , file.path(output_dir , " latest_v2.json" ), auto_unbox = TRUE )
172+
173+ jsonlite :: write_json(json , path , auto_unbox = TRUE )
168174}
169175
176+ write_latest_json(
177+ v1_extent $ latest ,
178+ file.path(output_dir , " latest_v1.json" ),
179+ " latest v1 data" ,
180+ " D35252"
181+ )
182+ write_latest_json(
183+ v2_extent $ latest ,
184+ file.path(output_dir , " latest_v2.json" ),
185+ " latest v2 data" ,
186+ " 9E1B1B"
187+ )
188+
170189# --- Determine Timeline Event Dates for Vertical Lines ---
171190# We place v1 date labels (2020-2021) in the blank space under the Municipalities bar (y = 1.3),
172191# and v2 date labels (2022 onwards) above the Districts bar (y = 3.4).
173192# To keep a consistent visual rhythm and prevent vertical lines from intersecting text,
174193# all date labels sit neatly to the left of their respective vertical lines (hjust = 1.15).
175194vline_data <- tibble(
176- date = c(min( v1_dates ), max( v1_dates ), min( v2_dates ), max( v2_dates ) ),
195+ date = c(v1_extent $ start , v1_extent $ latest , v2_extent $ start , v2_extent $ latest ),
177196 label = c(start_v1_label , latest_v1_label , start_v2_label , latest_v2_label ),
178197 y_pos = c(1.3 , 1.3 , 3.4 , 3.4 ),
179198 hjust = 1.15
180- )
199+ ) | >
200+ filter(! is.na(date ))
181201
182202# We draw a clean, continuous vertical segment for each timeline date behind/adjacent to the text.
183203segment_data <- tibble(
184- date = c(min( v1_dates ), max( v1_dates ), min( v2_dates ), max( v2_dates )) ,
204+ date = vline_data $ date ,
185205 y = 0.5 ,
186206 yend = 3.25
187207)
0 commit comments