3

I am trying to put a small plot into a DT::dataTableOutput in shiny and while I can put a plot into a tableOutput with no problem, it doesn't display at all in the DT version.

library(shiny)
ui <- fluidPage(
  DT::dataTableOutput("data1"),
  tableOutput("data2")
)

server <- function(input, output) {
  output$data1 <- DT::renderDataTable({
    dat <- cars[1:5,]
    dat$test <- c("a","b","c","d",
      '<div id="testPlot1" class="shiny-plot-output" style="width: 100px ; height: 100px"></div>')
    dat
  },escape=FALSE)
  output$data2 <- renderTable({
    dat <- cars[1:5,]
    dat$test <- c("a","b","c","d",
      '<div id="testPlot2" class="shiny-plot-output" style="width: 100px ; height: 100px"></div>')
    dat
  }, sanitize.text.function = function(x) x)
  output$testPlot1 <- renderPlot({
    par(mar=c(0,0,0,0))
    plot(cars[[1]],cars[[2]])
  },height=100,width=100)
  output$testPlot2 <- renderPlot({
    par(mar=c(0,0,0,0))
    plot(cars[[1]],cars[[2]])
  },height=100,width=100)
  outputOptions(output, 'testPlot1', suspendWhenHidden=FALSE)
}

shinyApp(ui, server)

plot expected in red circle

jpd527
  • 1,543
  • 1
  • 14
  • 30

1 Answers1

0

I think the problem is that the table is rendered later.

A possibility is to render the plot with plotOutput and then to move it to the cell with JavaScript:

js <- c(
  "function(){",
  "  var $plot = $('#testPlot1');",
  "  var $td = $('#data1').find('table').find('tr:last-child').find('td:last-child');",
  "  $td.append($plot);",
  "}"
)

ui <- fluidPage(
  plotOutput("testPlot1", width = "100px", height = "100px"),
  DT::dataTableOutput("data1"),
  tableOutput("data2")
)

server <- function(input, output) {
  output$data1 <- DT::renderDataTable({
    dat <- cars[1:5,]
    dat$test <- c("a","b","c","d","")
    dat
  }, escape=FALSE, options = list(initComplete = JS(js)))
  output$testPlot1 <- renderPlot({
    par(mar=c(0,0,0,0))
    plot(cars[[1]],cars[[2]])
  },height=100,width=100)
}

shinyApp(ui, server)

enter image description here

Here I've selected the target cell by using the fact that it is the last cell of the last row. A more general strategy is to put a div with an id in the target cell, like this:

  output$data1 <- DT::renderDataTable({
    dat <- cars[1:5,]
    dat$test <- c("a","b","c","d",'<div id="target"></div>')
    dat
  }, escape=FALSE, options = list(initComplete = JS(js)))

and then you can select it like this:

js <- c(
  "function(){",
  "  var $plot = $('#testPlot1');",
  "  var $td = $('#data1 #target');",
  "  $td.append($plot);",
  "}"
)
Stéphane Laurent
  • 75,186
  • 15
  • 119
  • 225