0

I started with this post and the code from @Hallie Swan works great, but I want to change the last shape in the legend into a hollow triangle.

My impression is that it's challenging to draw a hollow triangle purely in CSS. Then I found that it might work if I can inline an svg tag (that draws a hollow triangle) in the customized CSS part in R. But I failed.

Here's the code from the original post, excluding the shiny part:

library(leaflet)

colors <- c("red", "white", "blue", "white", "blue", "red")
labels <- c("filled_square", "empty_square", "big_square", "empty_circle", "filled_circle", "big_circle")
sizes <- c(10, 20, 30, 10, 20, 30)
shapes <- c("square", "square", "square", "circle", "circle", "circle")
borders <- c("red", "blue", "black", "blue", "blue", "black")

addLegendCustom <- function(map, colors, labels, sizes, shapes, borders, opacity = 0.5){
  
  make_shapes <- function(colors, sizes, borders, shapes) {
    shapes <- gsub("circle", "50%", shapes)
    shapes <- gsub("square", "0%", shapes)
    paste0(colors, "; width:", sizes, "px; height:", sizes, "px; border:3px solid ", borders, "; border-radius:", shapes)
  }
  make_labels <- function(sizes, labels) {
    paste0("<div style='display: inline-block;height: ", 
           sizes, "px;margin-top: 4px;line-height: ", 
           sizes, "px;'>", labels, "</div>")
  }
  
  legend_colors <- make_shapes(colors, sizes, borders, shapes)
  # I added my modification here, see below
  legend_labels <- make_labels(sizes, labels)
  
  return(addLegend(map, colors = legend_colors, labels = legend_labels, opacity = opacity))
}

leaflet() %>% addTiles() %>% 
  addLegendCustom(colors, labels, sizes, shapes, borders)

What I've tried:

Based on the original code, I tried modifying the last element in the legend_colors vector, like so:

legend_colors[length(legend_colors)] <- "url('data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' height='20' width='30'><polygon points='15,3 25,15 5,15' style='fill:transparent;stroke:black;stroke-width:3' /></svg>')"

But no triangle was displayed after I added the above line to the original script. The place where the triangle is supposed to appear is empty:

A screenshot of what it looks like at the moment:
A screenshot of what it looks like at the moment

Based on the information in another post, for this last legend shape I'm trying to modify, the CSS code constructed under the hood by leaflet should be (please correct me if I'm wrong here):

        {
    background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' height='20' width='30'><polygon points='15,3 25,15 5,15' style='fill:transparent;stroke:black;stroke-width:3' /></svg>");
    opacity: 0.5;
}
Zach Jensz
  • 3,650
  • 5
  • 15
  • 30
Yee
  • 13
  • 3

1 Answers1

1

I figured it out. The solution is to feed the Base64 data URI of the image into R. I created a png image for the hollow triangle first, saved it into a size I want, and used this free service to get the Base64 data URI.

Here is the R code (for the part I'm revising only):

  legend_colors[length(legend_colors)] <- "url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAYAAADhAJiYAAAAAXNSR0IArs4c6QAABQJJREFUWEfNl3tMW1Ucx3+37eU6WtAYEx5qENQo5TUL1uoSCmSOP4UARZ1DHoNtmdkf/AEtZPERQkv4w0yNQsLTmEUeKeJ8zWVAiRpbLH/wKJAgSHzQGP+BVMbt6bnXnKZn6Qjr7QOXNSEklHv76ff8Pt9zLgP32Yu5z3jgqIDofcRYv+BRAcXKcfv6WIHo9ccAgKSzH7hz1EnFCiQHACyTyT4BgF1BEFoBwP+3aCOLBUgWSCUDANYD6TwJAO4AjBANVCxANIlrer1ex/N8nMPh+EoQhNOxpBQtkB9GoVCUYIxvulyuqzs7O5xOp6tgWVaLEJqLFioaIHINXa6Fmpoa1fDw8BcAwJSVlRkmJye3AEB3L4HoIJ9TKpU9KysrgykpKV4yT+vr66q8vLw3EEKvYYw/jwYq0oTI/5OfBADY7Ojo+K29vX2W53klGWCO4zwtLS2nuru7HwKApwCADwx+2DUQKRBN5/20tLRLS0tLPRzHKYJsEnd3d0GtVp9zu93vAMC7kaYUCRCdG/LN10ZGRm4aDIYVhNAxuVzuVxwhJOM4bq+vr++5xsbGFwCAVMJfgVTDqoFIgKjmXxcWFp6w2WxDGON4hmHuWA5RFMk997Va7dn5+Xky7K9HklK4QFTzk4Ig3LDb7WMFBQV/I4Ti5HL5HUAYY4ZlWX56evrxkpKSV1iW1SGE7OFChQMUrPlSbW1t/ODg4ARCSEWX6mAjY4xlLMt6Kioqqq1W6x8AoD1KIDK0PplMdkGlUn28vLw8kJqa6hVFUX5wuSgYWTaGYXwbGxuq3NzcM16v9zTG+Go4UFIJUc0TieadnZ2/mkymH4jmLMuGHNLAgHuMRuPLXV1dDwMA2ecka0AKiGp+JT09/a3FxcWeuLg4v+YME/pSUfSPlujxeES1Wn3e7Xa/JwjC21Iphbor1fxpovnY2NiNysrK1WDNpXZzWgMDAwPHGxoayHZCUvozVA2EAqKaf0t285mZmeHDNJeCIvMkiuItnU531ul0XgOAV0OldDcgqvkpURSv2+320fz8/H8QQuxBzaWAAjXgnZ2dfUyv15MaeBEh9PPdoA4DooNMfi/V19dz/f39k6E0DwPKXwNVVVWG8fFx0tzPRwJENb+YkJDwkcvlGkhOTg6puRQQrYHNzU1lTk5OjdfrPYMx/uwwqIMJ0XQeJJpbLJb11tbWsDSXgqI10NbWdtJsNj8SGHDyUEB0vN32B4Go5h9mZGRcWFhYIJqz4WguBRRcA1lZWee3t7c7BEG4DAD+FaHXBwNRzZ8BgBWr1fp9eXn5Gs/zD7AsG/Z5JhQYrYGhoaG8urq6lwJnpt+DayAYiGp+vbi4WDs1NRWV5mEkRbYVfw3Mzc19AwBVwbNEgajmpaIofudwOEY1Gk1UmksB0Rqw2WyPFhUVlSkUihM+n+8nChWsOFmy5aamJkVvb++XsWgeBpS/Bqqrqw2jo6PkOS4/GIhqfikxMfGKy+XqT0pKQqF2c6kPlHqf1sDW1pYyOzu7huf5NzHGn5IBp2cdcijfMpvNa0aj8ce9vT3J3VzqQ6XeJwMeHx//r8lkKrFYLEkAkA4At+gMfaDRaBqdTid5Rvdrfo9exF4hMzPz4urqqgUALpPj5nGE0C/Nzc2u0tLSDZ7nOYVCcSSaS3wp0efzkYeC/YmJiWd7enqeAIBcktA0ABQF2lLqfPR/BUcOe0Sqyf8AKIk/HsRz7OEAAAAASUVORK5CYII=')"
  
  legend_colors[length(legend_colors)] <- gsub("=')", 
                                               "='); width:36px; height:36px", 
                                               legend_colors[length(legend_colors)])

Note that the second part is to append more CSS code to control the size of the element. Just refer to the HTML source code to adjust the size as needed.

What the legend looks now

Yee
  • 13
  • 3