在 D3 工具提示中嵌入推文

问题描述 投票:0回答:1

我正在尝试构建一个自定义 D3 工具提示,使用来自publish.twitter.com 的复制/粘贴代码来显示推文小部件。

我正在 R 中使用plotly 设置绘图,并希望在单击相应的数据点时显示推文小部件(在此处使用此示例推文)。我已经设法使用here描述的方法来显示图像工具提示,并尝试对其进行调整以显示推文小部件。然而,虽然推文的文本、推文的 Twitter 句柄和日期会在单击时显示,但推文小部件却不会 (Tweet text is displayed, widget isn't.。“widgets.js”脚本源在 twitter 的复制/粘贴文本中提供,但似乎失败了,只显示推文文本等。

这是 R 中的一个最小示例:

# Load packages

library(plotly)
library(htmlwidgets)
library(htmltools)
library(magrittr)


# Define text and position
x <- 1 
y <- 1

label <- c("Click here for tweet")

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

# Define plot, provide .js file with custom tweet tooltip & add D3 dependency
p <- plot_ly() %>%
  add_text(x = x, y = y, text = label) %>%
  htmlwidgets::onRender(readLines("tweet_tooltip.js")) 

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

# Render plot
p

其中“tweet_tooltip.js”包含以下函数:


// tweet_tooltip.js
// Adapted from https://stackoverflow.com/questions/71601216/r-plotly-display-image-on-hover

function(el) {
    
    // Define tooltip
    var tooltip = d3.select('#' + el.id + ' .svg-container')
      .append("div")
      .attr("class", "my-custom-tooltip");
      
    el.on('plotly_click', function(d) {
      
      var pt = d.points[0];
        
      // Choose a location (on the data scale) to place the image: upper left corner
      var x = pt.xaxis.range[0];
      var y = pt.yaxis.range[1];
      
      
      // Transform the data scale to the pixel scale
      var xPixel = pt.xaxis.l2p(x) + pt.xaxis._offset;
      var yPixel = pt.yaxis.l2p(y) + pt.yaxis._offset;
      
      // Define tweet variable with twitter blockquote/script
      var tweet = '<blockquote class="twitter-tweet"><p lang="en" dir="ltr">How much is it?</p>&mdash; Elon Musk (@elonmusk) <a href="https://twitter.com/elonmusk/status/943902052542849024?ref_src=twsrc%5Etfw">December 21, 2017</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>'
      
      // Add to tooltip & define position
      tooltip.html(tweet)
       .style("position", "absolute")
       .style("left", xPixel + "px")
       .style("top", yPixel + "px");
      
      tooltip

    });
}


javascript r d3.js plotly tooltip
1个回答
0
投票

这对我来说仍然显得笨拙(所以可能有更好的答案)。您将无法在 Plotly SVG 中添加 iframe,但您可以使其看起来像您所做的那样。另外,如果你不小心,因为它是一个小部件,就像 Plotly 一样,你会覆盖绘图。

您将不会在 RStudio 的预览窗格中看到 Twitter 小部件。您必须在浏览器中发送绘图。如果您不确定如何操作,请告诉我。

如果您使用我的代码,则不需要

D3
。然而,尽管存在差异,唯一真正改变的是 Twitter 小部件element 的放置位置。我在所有 Plotly 内容之后添加了
tooltip
元素,但仍在包含 Plotly 的
htmlwidget
内。

在此代码中,我没有将

js
代码设为单独的文件,它位于我的 R 脚本中。由于它是在 R 脚本中,因此您会看到诸如
\'
而不是
'
之类的内容,以便 R 知道这些是嵌套引用。如果使用单独的 JS 文件,则不会这样做。例如,在我的代码中创建
tooltip
时,您会看到
var tooltip = $("<div class=\'my-custom
...在单独的JS脚本中,它将被写为
var tooltip = $("<div class='my-custom
...

这是我使用的代码。

plot_ly() %>%
  add_text(x = x, y = y, text = label) %>%
  htmlwidgets::onRender(
    'function(el) {
      // Define tooltip
      var tooltip = $("<div class=\'my-custom-tooltip\'></div>").insertAfter("#js-plotly-tester");
      
      el.on("plotly_click", function(d) {
        var pt = d.points[0];
        
        // Choose a location (on the data scale) to place the image: upper left corner
        var x = pt.xaxis.range[0];
        var y = pt.yaxis.range[1];
        
        // Transform the data scale to the pixel scale
        var xPixel = pt.xaxis.l2p(x) + pt.xaxis._offset;
        var yPixel = pt.yaxis.l2p(y) + pt.yaxis._offset;
        
        // Define tweet variable with twitter blockquote/script
        var tweet = "<blockquote class=\'twitter-tweet\'><p lang=\'en\' dir=\'ltr\'>How much is it?</p>&mdash; Elon Musk (@elonmusk) <a href=\'https://twitter.com/elonmusk/status/943902052542849024?ref_src=twsrc%5Etfw\'>December 21, 2017</a></blockquote> <script async src=\'https://platform.twitter.com/widgets.js\' charset=\'utf-8\'></script>";
    
        // Add to tooltip & define position
        tooltip.html(tweet)
          .css({position: "absolute", left: xPixel + "px", top: yPixel + "px"});
        
        tooltip
      });
  }')

触发 Twitter 小部件和它显示之间有轻微的延迟(不到一秒)。

© www.soinside.com 2019 - 2024. All rights reserved.