【问题标题】:Is it possible to switch between multiple legends when switching between base groups?在基组之间切换时是否可以在多个图例之间切换?
【发布时间】:2019-02-22 21:18:09
【问题描述】:

我正在使用 r 中的传单可视化一些矢量数据,其中包含用户可能感兴趣的多个非空间变量。我希望允许用户选择一个变量来确定特征的颜色。我使用addLayersControl 函数的baseGroups 参数来完成此操作,其中每个组是具有不同调色板的相同数据。这可以很好地切换功能本身的颜色,但不允许我在图例之间切换 - 我添加的每个图例总是显示,即使我在 addLegend 中使用适当的 group。请参阅下面的示例代码和屏幕截图:

data <- data.frame(long = c(-93.2, -93, -93.5), lat = c(44.9, 45, 44.9), 
               var1 = c(1,2,3), var2 = c(10, 9, 1))

pal1 <- colorNumeric(palette = "Blues", domain = data$var1)
pal2 <- colorNumeric(palette = "Reds", domain = data$var2)

leaflet(data) %>%
  addCircleMarkers(color = ~pal1(var1), group = "var1") %>%
  addCircleMarkers(color = ~pal2(var2), group = "var2") %>%
  addLegend(pal = pal1, values = ~var1, group = "var1") %>%
  addLegend(pal = pal2, values = ~var2, group = "var2") %>%
  addLayersControl(baseGroups = c("var1", "var2"), position = "topleft")

如果我在我的图层控件中将baseGroups 替换为overlayGroups,这将按预期工作,并且仅显示所选组的图例。但是,此选项并不理想,因为我不希望用户能够选择多个组或取消选择所有组。

Thesequestions 与我的非常相似,但公认的解决方案都使用overlayGroups,而我想坚持使用baseGroups。如果可能的话,我也希望避免使用闪亮。

【问题讨论】:

    标签: r leaflet r-leaflet


    【解决方案1】:

    似乎baseGroups 中的图例不会像overlayGroups 中那样删除/重新添加,即使在调用hideGroup("var1") 之后,图例的持久性也可以进一步证明这一点。

    一个粗略的解决方法是添加一个事件处理程序以根据当前选择的baseGroups 组使用group = "&lt;groupName&gt;" 作为键来隐藏/取消隐藏图例,并且不需要更改任何其他内容。例如:

    htmlwidgets::onRender("
        function(el, x) {
          var updateLegend = function () {
              var selectedGroup = document.querySelectorAll('input:checked')[0].nextSibling.innerText.substr(1);
    
              document.querySelectorAll('.legend').forEach(a => a.hidden=true);
              document.querySelectorAll('.legend').forEach(l => {
                if (l.children[0].children[0].innerText == selectedGroup) l.hidden=false;
              });
          };
          updateLegend();
          this.on('baselayerchange', e => updateLegend());
        }")
    

    演示

    演示来源

    require(leaflet)
    
    
    data <- data.frame(long = c(-93.2, -93, -93.5), lat = c(44.9, 45, 44.9), 
                       var1 = c(1,2,3), var2 = c(10, 9, 1))
    
    pal1 <- colorNumeric(palette = "Blues", domain = data$var1)
    pal2 <- colorNumeric(palette = "Reds", domain = data$var2)
    
    leaflet(data) %>%
      addCircleMarkers(color = ~pal1(var1), group = "var1") %>%
      addCircleMarkers(color = ~pal2(var2), group = "var2") %>%
      addLegend(pal = pal1, values = ~var1, group = "var1") %>%
      addLegend(pal = pal2, values = ~var2, group = "var2") %>%
      addLayersControl(baseGroups = c("var1", "var2"), 
                       position = "topleft",
                       options = layersControlOptions(collapsed=F)) %>%
      htmlwidgets::onRender("
        function(el, x) {
          var updateLegend = function () {
              var selectedGroup = document.querySelectorAll('input:checked')[0].nextSibling.innerText.substr(1);
    
              document.querySelectorAll('.legend').forEach(a => a.hidden=true);
              document.querySelectorAll('.legend').forEach(l => {
                if (l.children[0].children[0].innerText == selectedGroup) l.hidden=false;
              });
          };
          updateLegend();
          this.on('baselayerchange', e => updateLegend());
        }")
    

    【讨论】:

    • 这个答案很好,但如果将传单对象输出到使用标签的 r markdown 文档,它似乎不起作用。
    • 使用'overlayGroups'而不是'baseGroups'不是更容易吗?因为那样你就不一定需要'htmlwidgets::onRender'
    • @g07kore 是的,它更容易,并且 PO 知道这种方法,但正如 PO 所说“这个选项并不理想,因为我不希望用户能够选择多个组或取消选择所有组”。
    • 这非常有用但很脆弱。 JS 代码要求图例标题与图层控件中的名称完全相同。这很容易被打破,例如,如果你给图例一个标题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-24
    • 2013-10-30
    • 1970-01-01
    • 1970-01-01
    • 2020-12-02
    相关资源
    最近更新 更多