R语言 在Map中悬停时显示图像

b1payxdu  于 2023-09-27  发布在  其他
关注(0)|答案(1)|浏览(93)

下面是两个很棒的例子,说明如何在R中的一个点上显示图像:12。我能让他们工作得很好,直到我把情节变成Map。然后方法中断。有谁能帮忙修改一下它,让它能在Map上工作吗?

library(dplyr)
library(plotly)

df <- data.frame(x = c(-81.026, -81.025, -81.028), y = c(44.13, 44.14, 44.15), 
     url = c("https://upload.wikimedia.org/wikipedia/commons/6/6f/Beethoven.jpg",
        "https://upload.wikimedia.org/wikipedia/commons/4/47/Croce-Mozart-Detail.jpg",
        "https://upload.wikimedia.org/wikipedia/commons/6/6a/Johann_Sebastian_Bach.jpg"))

d3 <- htmltools::htmlDependency(
  "d3", "7.3",
  src = c(href = "https://cdnjs.cloudflare.com/ajax/libs/d3/7.3.0/"),
  script = "d3.min.js"
)

js <- '
function(el) {
  var tooltip = d3.select("#" + el.id + " .svg-container")
    .append("div")
    .attr("class", "my-custom-tooltip");

  el.on("plotly_hover", function(d) {
    var pt = d.points[0];
    var x = pt.xaxis.range[0];
    var y = pt.yaxis.range[1];
    var xPixel = pt.xaxis.l2p(x) + pt.xaxis._offset;
    var yPixel = pt.yaxis.l2p(y) + pt.yaxis._offset;
    var img = "<img src=\\\"" +  pt.customdata + "\\\" width=100>";
    tooltip.html(img)
      .style("position", "absolute")
      .style("left", xPixel + "px")
      .style("top", yPixel + "px");
    tooltip.transition()
      .duration(300)
      .style("opacity", 1);
  });

  el.on("plotly_unhover", function(d) {
    tooltip.transition()
      .duration(500)
      .style("opacity", 0);
  });
}
'

这工作,并显示一个图像悬停

p <-plot_ly(df, x = ~x, y = ~y, type = "scatter", mode = "markers", hoverinfo = ~x, customdata = ~url) %>%
  htmlwidgets::onRender(js)

p$dependencies <- c(p$dependencies, list(d3))
p

这不...

p <- plot_ly(df, lon = ~x, lat = ~y, type = "scattermapbox", mode = "markers", hoverinfo = ~x, customdata = ~url) %>%
  layout(mapbox = list(style = "white-bg", sourcetype = 'raster', zoom = 4,
                      center = list(lon = -81 ,lat= 44),
                      layers = list(list(below = 'traces', sourcetype = "raster",
                                         source = list("https://basemap.nationalmap.gov/arcgis/rest/services/USGSImageryOnly/MapServer/tile/{z}/{y}/{x}"))))) %>%
  htmlwidgets::onRender(js)

p$dependencies <- c(p$dependencies, list(d3))
p
uz75evzq

uz75evzq1#

它不起作用的原因是Plotly的结构随着Map的变化而发生了显着变化。虽然x轴和y轴的概念显然仍然存在,但Plotly并没有将轴与Map相关联。
我为你提供了两个解决方案。第一个基本上是对原始onRender的改编。第二个修改了一点。
在原始格式中,当您放大打印/Map时,图像会移出可视空间。使用第二个选项,如果不缩放,它看起来将与第一个图相同。如果放大,您将看到无论缩放位置如何,图像都保持可见。
对象js的第一次调整

js <- '
function(el) {
  var tooltip = d3.select("#" + el.id + " .svg-container")  /* identify container */
    .append("div")
    .attr("class", "my-custom-tooltip");

  el.on("plotly_hover", function(d) {                     /* add content on hover */ 
      pt = d.points[0];
      img = "<img src=\\\"" + pt.customdata + "\\\" width=100>";  /* image in hover */ 
                                        /* the position of the map on the webpage */ 
      bx = document.querySelector("div.mapboxgl-map").getBoundingClientRect();
      tooltip.html(img)
        .style("position", "absolute")
        .style("left", bx.left + "px") /* assign left and top to match map position*/
        .style("top", bx.top + "px");
      tooltip.transition()         
        .duration(300)
        .style("opacity", 1);
  })
  el.on("plotly_unhover", function(d) {  /* collapse image when tooltip collapses */
      tooltip.transition()
      .duration(500)
      .style("opacity", 0);
  });
}
'

对象js的第二次调整,因此图像在缩放/平移等时是可见的。

js2 <- '
function(el) {
  var tooltip = d3.select("#" + el.id + " .svg-container")  /* identify container */
    .append("div")
    .attr("class", "my-custom-tooltip");

  el.on("plotly_hover", function(d) {                     /* add content on hover */ 
      pt = d.points[0];
      console.log(pt);
      img = "<img src=\\\"" +  pt.customdata + "\\\" width=100>";  /* image in hover */ 
                                        /* the position of the map on the webpage */ 
      bx = document.querySelector("div.mapboxgl-map").getBoundingClientRect();
      var h = window.innerHeight;       /* get viewers screen size */
      var w = window.innerWidth;
      tooltip.html(img)             /* calculate % left/right map to screen position */
        .style("position", "absolute")
        .style("left", (bx.left/w * 100) + "vw")
        .style("top", (bx.top/h * 100) + "vh");
      tooltip.transition()
        .duration(300)
        .style("opacity", 1);
  })
  el.on("plotly_unhover", function(d) {  /* collapse image when tooltip collapses */
      tooltip.transition()
      .duration(500)
      .style("opacity", 0);
  });
}
'

如果你有任何问题,请告诉我。

相关问题