# id = bank slug (internal vertex name); nombre = display name
nodos <- tibble(
id = V(chronnet)$name,
nombre = V(chronnet)$bank_name, pais = V(chronnet)$country,
lon = V(chronnet)$lon, lat = V(chronnet)$lat,
monto_total = V(chronnet)$monto_total, tx_total = V(chronnet)$tx_total,
first = V(chronnet)$first, last = V(chronnet)$last
) %>% filter(!is.na(lat), !is.na(lon), monto_total > 0)
# as_long_data_frame already carries from_lat/from_lon/to_lat/to_lon: no joins
el <- as_long_data_frame(chronnet) %>%
transmute(lat_o = from_lat, lon_o = from_lon, lat_d = to_lat, lon_d = to_lon,
monto, from_n = from_bank_name, to_n = to_bank_name) %>%
filter(monto > 0, !is.na(lat_o), !is.na(lat_d)) %>%
arrange(desc(monto)) %>% slice_head(n = 500)
# Node color by country (extended palette for many countries)
n_paises <- length(unique(nodos$pais))
pal_pais <- colorFactor(colorRampPalette(brewer.pal(8, "Set2"))(n_paises), nodos$pais)
leaflet(nodos) %>%
addProviderTiles(providers$OpenStreetMap) %>%
addCircleMarkers(
radius = ~scales::rescale(log1p(monto_total), to = c(3, 12)),
color = ~pal_pais(pais), fillOpacity = 0.75, stroke = FALSE, group = "Banks",
label = lapply(paste0("<b>", nodos$nombre, "</b> (", nodos$pais, ")<br>",
"💰 ", dollar(nodos$monto_total), " | 🔢 ", comma(nodos$tx_total), " tx<br>",
"📍 ", round(nodos$lat,2), ", ", round(nodos$lon,2), "<br>",
"🗓️ ", nodos$first, " → ", nodos$last), htmltools::HTML)) %>%
addPolylines(data = el, lat = ~c(lat_o, lat_d), lng = ~c(lon_o, lon_d),
group = "Flows", color = "#B45309", weight = 1.2, opacity = 0.35,
label = ~paste0(from_n, " → ", to_n, "<br>💰 ", dollar(monto), " reported")) %>%
addLayersControl(overlayGroups = c("Banks", "Flows"),
options = layersControlOptions(collapsed = FALSE)) %>%
setView(lng = 0, lat = 20, zoom = 2)