-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #72 from trafficonese/layergroupcollision
Layergroupcollision
- Loading branch information
Showing
15 changed files
with
1,216 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
layergroupCollisionDependency <- function() { | ||
list( | ||
htmltools::htmlDependency( | ||
"lfx-layergroupcollision", | ||
version = "1.0.0", | ||
src = system.file("htmlwidgets/lfx-layergroupcollision", | ||
package = "leaflet.extras2" | ||
), | ||
script = c( | ||
"rbush.min.js", | ||
"Leaflet.LayerGroup.Collision.js", | ||
"layergroup-binding.js" | ||
), | ||
all_files = TRUE | ||
) | ||
) | ||
} | ||
|
||
#' Add LayerGroup Collision Plugin | ||
#' | ||
#' @description Integrates the LayerGroup Collision plugin into a Leaflet map, | ||
#' which hides overlapping markers and only displays the first added marker in a | ||
#' collision group. Markers must be static; dynamic changes, dragging, and | ||
#' deletions are not supported. | ||
|
||
#' The function transforms spatial data into GeoJSON format and uses `L.DivIcon`, | ||
#' allowing you to pass HTML content and CSS classes to style the markers. | ||
#' | ||
#' @param group the name of the group. It needs to be single string. | ||
#' @param margin defines the margin between markers, in pixels | ||
#' @return A leaflet map object with the LayerGroup Collision plugin added. | ||
#' @export | ||
#' | ||
#' @inheritParams addDivicon | ||
#' @references \url{https://github.com/MazeMap/Leaflet.LayerGroup.Collision} | ||
#' | ||
#' @name LayerGroupCollision | ||
#' @examples | ||
#' library(leaflet) | ||
#' library(sf) | ||
#' library(leaflet.extras2) | ||
#' | ||
#' df <- sf::st_as_sf(atlStorms2005) | ||
#' df <- suppressWarnings(st_cast(df, "POINT")) | ||
#' df$classes <- sample(x = 1:5, nrow(df), replace = TRUE) | ||
#' | ||
#' leaflet() %>% | ||
#' addProviderTiles("CartoDB.Positron") %>% | ||
#' leaflet::addLayersControl(overlayGroups = c("Labels")) %>% | ||
#' addPolylines(data = sf::st_as_sf(atlStorms2005), label = ~Name) %>% | ||
#' addLayerGroupCollision( | ||
#' data = df, margin = 40, | ||
#' html = ~ paste0( | ||
#' '<div style="width: max-content; background-color: #cbc0c04f" class="custom-html">', | ||
#' '<div class="title">', Name, "</div>", | ||
#' '<div class="subtitle">MaxWind: ', MaxWind, "</div>", | ||
#' "</div>" | ||
#' ), | ||
#' className = ~ paste0("my-label my-label-", classes), | ||
#' group = "Labels" | ||
#' ) | ||
addLayerGroupCollision <- function( | ||
map, group = NULL, | ||
className = NULL, html = NULL, | ||
margin = 5, data = getMapData(map)) { | ||
map$dependencies <- c(map$dependencies, layergroupCollisionDependency()) | ||
|
||
## Make Geojson and Assign Class & HTML columns ########### | ||
if (!inherits(data, "sf")) { | ||
data <- sf::st_as_sf(data) | ||
} | ||
data$className__ <- evalFormula(className, data) | ||
data$html__ <- evalFormula(html, data) | ||
geojson <- yyjsonr::write_geojson_str(data) | ||
class(geojson) <- c("geojson", "json") | ||
|
||
## Derive Points and Invoke Method ################## | ||
pts <- derivePoints( | ||
data, NULL, NULL, TRUE, TRUE, | ||
"addLayerGroupCollision" | ||
) | ||
invokeMethod( | ||
map, NULL, "addLayerGroupCollision", | ||
geojson, group, margin | ||
) %>% | ||
expandLimits(pts$lat, pts$lng) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
library(shiny) | ||
library(leaflet) | ||
library(sf) | ||
library(leaflet.extras2) | ||
options("shiny.autoreload" = TRUE) | ||
|
||
df <- sf::st_as_sf(atlStorms2005) | ||
df <- suppressWarnings(st_cast(df, "POINT")) | ||
df <- df[sample(1:nrow(df), 150, replace = FALSE),] | ||
df$classes = sample(x = 1:5, nrow(df), replace = TRUE) | ||
|
||
## Ordering is important | ||
df <- df[order(df$classes, decreasing = FALSE),] | ||
|
||
ui <- fluidPage( | ||
## CSS-style ############ | ||
tags$head(tags$style(" | ||
.my-label { | ||
background: white; | ||
border: 1px solid #888; | ||
position: relative; | ||
display: inline-block; | ||
white-space: nowrap; | ||
} | ||
.my-label-1 { font-size: 28px; background-color: red; top: -26px; } | ||
.my-label-2 { font-size: 24px; background-color: orange; top: -25px; } | ||
.my-label-3 { font-size: 22px; background-color: yellow; top: -24px; } | ||
.my-label-4 { font-size: 16px; background-color: green; top: -23px; } | ||
.my-label-5 { font-size: 15px; background-color: lightgreen; top: -22px; } | ||
")), | ||
leafletOutput("map", height = 800) | ||
) | ||
|
||
## Server ########### | ||
server <- function(input, output, session) { | ||
output$map <- renderLeaflet({ | ||
leaflet() %>% | ||
addProviderTiles("CartoDB.Positron") %>% | ||
leaflet::addLayersControl(overlayGroups = c("Labels")) %>% | ||
addLayerGroupCollision(data = df | ||
, html = ~paste0( | ||
'<div class="custom-html">', | ||
'<div class="title">', Name, '</div>', | ||
'<div class="subtitle">MaxWind: ', MaxWind, '</div>', | ||
'</div>' | ||
) | ||
, className = ~paste0("my-label my-label-", classes) | ||
, group = "Labels" | ||
) | ||
|
||
}) | ||
} | ||
shinyApp(ui, server) |
Oops, something went wrong.