曲线轴标题上的工具提示

时间:2017-10-18 11:53:07

标签: javascript r shiny plotly r-plotly

我希望在绘图图形的轴标题上有一个工具提示。

这是我的尝试:

x <- y <- 1:10
dat <- expand.grid(x=x, y=y)
dat <- transform(dat, z=x*y)

jscode <- '
$(document).ready(function(){
  setTimeout(function(){
    $($("#heatmap .g-xtitle text")[0]).attr("title", "hello").attr("data-toggle", "tooltip");
  }, 5000);
})
'

library(shiny)
library(plotly)
shinyApp(
  ui <- fluidPage(
    tags$head(tags$script(jscode)),
    plotlyOutput("heatmap")
  ),
  server = function(input, output){
    output$heatmap <- renderPlotly(plot_ly() %>%
      add_trace(data=dat, x=~x, y=~y, z=~z, type="heatmap") %>%
      layout(
        xaxis = list(title="foo") 
      )
    )
  }
)

JS代码按预期将属性data-toggletitle设置为x轴标题的容器,但不显示工具提示。我也在控制台中尝试了类似$($("#heatmap .g-xtitle text")[0]).tooltip()的内容,但没有任何反应。

2 个答案:

答案 0 :(得分:1)

我认为您的代码存在一些问题:

  1. Plotly不喜欢它编辑的SVG代码。即使您针对正确的元素,Plotly可能会立即删除您添加的内容。
  2. 您错过了启用应用工具提示的代码。
  3. 当我想将工具提示放在刻度标签上时,我遇到了一个非常类似的问题。用自定义CSS和JS攻击它需要花费一些时间。我们的想法是添加一个div(矩形),它完美地覆盖了您想要使用工具提示丰富的元素。然后将该矩形的CSS opacity设置为0以隐藏它。但是一旦你将它悬停在这个矩形上的工具提示就会起作用(即使它是不可见的)。这是一个可视化矩形形状的代码。

    x <- y <- 1:10
    dat <- expand.grid(x = x, y = y)
    dat <- transform(dat, z = x * y)
    
    jscode <- "
    $(document).ready(function() {
        // Enable tooltips app-wise
        $(\"[data-toggle='tooltip']\").tooltip({container: 'body'}); 
    });
    "
    
    csscode <- HTML('
        .plot-container {
            position: relative;
        }
        .xaxis-container {
            height: 20px;
            position:absolute;
            bottom: 0;
            left: 40px;
            background: #bfb9b9;
            opacity: 0.3;
        }
        .xaxis-tooltip {
            width: 30px;
            height: 20px;
            background: #000;
            margin:auto;
        }
    ')
    
    library(shiny)
    library(plotly)
    shinyApp(
        ui <- fluidPage(
            tags$head(
                tags$script(jscode),
                tags$style(csscode)
            ),
            div(class = 'plot-container',
                plotlyOutput("heatmap"),
                div(
                    class = "xaxis-container",
                    div(class = "xaxis-tooltip", "data-toggle" = "tooltip", "title" = "hello")
                )
            )
        ),
        server = function(input, output) {
            output$heatmap <- renderPlotly({
                plot_ly() %>%
                    add_trace(
                        data = dat,
                        x =  ~ x,
                        y =  ~ y,
                        z =  ~ z,
                        type = "heatmap"
                    ) %>%
                    layout(xaxis = list(title = "foo")) %>%
                    # We can't just center the rectangle relative to the entire plot area.
                    # Instead, we need to do it relative to the draglayer.
                    # This code sets proper width of .xaxis-container on app start.
                    htmlwidgets::onRender(
                        "
                        function(el, x) {
                            var width = $('.draglayer')[0].getBoundingClientRect().width;
                            $('.xaxis-container').css('width', width);
                        }
                        "
                    )
            })
        }
    )
    

    将第21行中的opacity: 0.3;更改为opacity: 0;以获得功能完善的解决方案。

答案 1 :(得分:0)

注意:很遗憾,我还没有解决您的问题,但希望此信息有用。祝你好运!

背景:SVG

  1. plotly创建的地块为Scalable Vector Graphics<svg>

  2. <svg>的工具提示必须添加为child element named <title>

  3. <title>应该是其父级的first child element

  4. 新的<svg>元素必须为created in the SVG namespace

  5. SVG工具提示:矩形与Plotly x轴

    作为概念验证,我在您的示例中添加了<svg>矩形。使用JS,然后我添加了<title>元素作为<rect>元素的第一个子元素,它在矩形上生成工具提示。

    svg rectangle tooltip

    但是,遵循plotly热图的相同步骤不会在x轴标题上生成工具提示,尽管将<title>元素添加到x轴标题容器中。

    svg plotly tooltip

    <强>代码

    library(shiny)
    library(plotly)
    
    x <- y <- 1:10
    dat <- expand.grid(x=x, y=y)
    dat <- transform(dat, z=x*y)
    
    ### Create a <svg> rectangle element
    testRect <- '<svg width="250" height="75" xmlns="http://www.w3.org/2000/svg">
                    <g class="test-rect">
                        <rect x="10" y="10" width="200" height="50" 
                            style="fill:wheat; stroke:blue; stroke-width:1px"/>
                    </g>
                </svg>'
    
    ### Add a first child title element to the rectangle <svg>
    ### Hovering over the rectangle displays the tooltip
    jscode_testRect <- '$(document).ready(function(){
        setTimeout(function(){
            var titleRect = document.createElementNS("http://www.w3.org/2000/svg", "title");
            titleRect.textContent = "rectangle tooltip";
            var testRect = document.getElementsByClassName("test-rect")[0];
            testRect.insertBefore(titleRect, testRect.childNodes[0]); 
        }, 500);
    });'
    
    ### Add a first child title element to the SVG
    ### Hovering over the x-axis title doesn't display tooltip
    jscode_xaxisPlotly <- '$(document).ready(function(){
        setTimeout(function(){
            var titleAxis = document.createElementNS("http://www.w3.org/2000/svg", "title");
            titleAxis.textContent = "x-axis tooltip";
            var gXtitle = document.getElementsByClassName("g-xtitle")[0];
            gXtitle.insertBefore(titleAxis, gXtitle.childNodes[0]); 
        }, 500);
    });'
    
    shinyApp(
        ui <- fluidPage(
            tags$head(tags$script(HTML(jscode_testRect))),
            tags$head(tags$script(HTML(jscode_xaxisPlotly))),
            h4("<svg> rectangle - tooltip is functional"),
            tags$div(HTML(testRect)),
            h4("plotly heatmap - tooltip does not work"),
            plotlyOutput("heatmap"),
            br(),
            br()
        ),
        server = function(input, output){
            output$heatmap <- renderPlotly(plot_ly() %>%
                                               add_trace(data=dat, x=~x, y=~y, z=~z, type="heatmap") %>%
                                               layout(
                                                   xaxis = list(title="foo"),
                                                   title = "Title"
                                               )
            )
        }
    )