Thursday, 19 October 2023

Mapbox interactivity where values change in information window based on hover using R mapboxapi and mapboxer

I'm trying to get a mapbox, which changes layers on different zooms, to change values in an information window on mouse hover (like this example) using R's mapboxapi, mapboxer, and htmlwidgets. Kyle Walker's provides a great example of creating a legend, which used this example on creating a legend and I adapted below, but I'm struggling with translating the html and javascript code into the appropriate html chunk to adapt to my needs. My thinking is that the mapbox example requires pulling from a style, which might need to be upload to mapbox to operate and I need to do this all in html.

librarian::shelf(mapboxapi, mapboxer, htmltools, htmlwidgets)

or_evictions <- mapbox_source(
  type = "vector",
  url = paste0("mapbox://docthomas.oregon_evictions") 
)

eviction_map <- 
  mapboxer(zoom = 5.7, style = basemaps$Mapbox$light_v10,
           center = c(-120.5, 44.2),
           token = public_token) %>%
  add_layer(
    style = list(
      id = "county",
      type = "fill",
      source = or_evictions,
      "source-layer" = "counties",
      paint = list(
        "fill-color" = list(
          "interpolate",
          list("linear"),
          list("get", "avg_evr_all"),
          0, "#FFFFFF", 
          2, "#fecc5c", 
          6, "#fd8d3c", 
          12, "#f03b20", 
          25, "#51087e"
        ),
        "fill-opacity" = list(
          "case",
          list("==", list("get", "avg_evr_all"), NA),
          0.1,
          0.4
        )
      ),
      maxzoom = 7
    ),
    popup = "<br/>Eviction Rate: %")  %>%
  add_layer(
    style = list(
      id = "tracts",
      type = "fill",
      source = or_evictions,
      "source-layer" = "tracts",
      paint = list(
        "fill-color" = list(
          "interpolate",
          list("linear"),
          list("get", "avg_evr_all"),
          0, "#FFFFFF", 
          2, "#fecc5c", 
          6, "#fd8d3c", 
          12, "#f03b20", 
          25, "#51087e"
        ),
        "fill-opacity" = list(
          "case",
          list("==", list("get", "avg_evr_all"), NA),
          0.1,
          0.4
        )
      ),
      minzoom = 7
    ),
    popup = "<br/>Eviction Rate: %")

eviction_map
#
# Add legend and other dynamics
# --------------------------------------------------------------------------

style <- htmltools::HTML(
  "
  <style>
    @import url('https://fonts.googleapis.com/css2?family=Roboto&display=swap');

    h2 {
    font-size: 14px;
    font-family: 'Roboto';
    line-height: 20px;
    margin-bottom: 10px;
    }

    #legend {
    position: fixed;
    border-radius: 10px;
    top:50px;
    left:50px;
    margin: 10px;
    width: 120px;
    background-color: #ffffff80;
    padding: 10px 20px;
    z-index: 1002;
    }

    .content {
    margin-bottom: 20px;
    }

    .row {
    height: 12px;
    width: 100%;
    }

    .colors {
    background: linear-gradient(
    to right,
    #FFFFFF, 
    #fecc5c, 
    #fd8d3c, 
    #f03b20, 
    #51087e
    );
    margin-bottom: 5px;
    }

    .label {
    width: 30%;
    display: inline-block;
    text-align: center;
    font-family: 'Roboto';
    }
    </style>
  "
)

legend <- htmltools::HTML(
  '
<div id="legend">
<div class="content">
<h2>Eviction Rate</h2>
<div class="row colors"></div>
<div class="row labels">
<div class="label">0%</div>
<div class="label">   </div>
<div class="label">25+%</div>
</div>
</div>
  '
)

info <- htmltools::HTML(
 ' 
<div id="info"></div>
<div class="map-overlay" id="features">
<h2>Yearly average eviction rate</h2>
<div id="avg_evr_all"><p>Hover over a county or tract!</p></div>
</div>


map.on("mousemove", (event) => {
  const avg_evr_all = .queryRenderedFeatures(event.point, {
    layers: ["or_eviction"]
  });
  document.getElementById("pd").innerHTML = avg_evr_all.length
    ? `<h3>${avg_evr_all[0].properties.name}</h3><p><strong><em>${avg_evr_all[0].properties.density}</strong> people per square mile</em></p>`
    : `<p>Hover over a state!</p>`;
});

  '
)

# test <- 
  eviction_map %>%
  htmlwidgets::prependContent(style) %>%
  htmlwidgets::appendContent(legend) %>% 
  htmlwidgets::appendContent(info)

Any help would be greatly appreciated!! Below is an example of what I'm getting. Ideally the bottom of the legend would show a different rate when hovering on either a county or a census tract (after zooming in). I can get a popup to work but really need hover functionality.

example map



from Mapbox interactivity where values change in information window based on hover using R mapboxapi and mapboxer

No comments:

Post a Comment