Eduardo Rocha
Eduardo Rocha

Reputation: 103

Want to have a column with images in a datatable; it works with URL but does not work with local paths

I am trying to add a column with only images into a datatable. However, this is the best I got so far:

enter image description here

I'm not a expert in programming so I've been looking on the web in order to find a solution but nothing seems to work. I've tried solutions like the one in How to embed an image in a cell a table using DT, R and Shiny , How to place an image in an R Shiny title , Adding logos/images to the side of a data table and others...

This is a shiny app and the images are stored locally in my computer. I don't know why so many posts refer to a www folder because I thought that RStudio would look to the directory set with setwd(), which I had done. But I even created this www folder with the images and I put my app.R inside (also tried with it outside), but nothing works. However, if I input an URL, the image is displayed, but I really need to do it with local paths for now. Maybe later I will use the URL but this is bugging me off and I would really appreciate a solution (excuse me for being such a noob). I've also seen somewhere that it could be solved by pressing 'Run App' instead of selecting the whole code and run it, but that didn't work as well.

To finish, here is the relevant part of the code (data is already loaded into RStudio):

library('shiny')
library('shinydashboard')
library('tidyverse')
library('data.table')
library('plotly')
library('DT')

setwd("C:/Users/directory/with/images/www")

ui <- dashboardPage(
  dashboardHeader(title="Visuals"),
  dashboardSidebar(
    sidebarMenu(
      menuItem("Units table w/ links", tabName = "tabU", icon = icon("table"))
)
tabItem(tabName="tabU",
              fluidRow(
                box(
                  DT::dataTableOutput("data"),
                  width=12),
              ))
)
)

server <- shinyServer(function(input, output, session) {

df <- reactiveValues(data = data.frame(
      Name = readUnits$label,
      Icon=c('<img src="img1.png" height="52"></img>',
             '<img src="img1.png" height="52"></img>',
             '<img src="img2.png" height="52"></img>',
             '<img src="img3.png" height="52"></img>',
             '<img src="img4.png" height="52"></img>',
             '<img src="img4.png" height="52"></img>',
             '<img src="img5.png" height="52"></img>',
             '<img src="img6.png" height="52"></img>',
             '<img src="img7.png" height="52"></img>',
             '<img src="img7.png" height="52"></img>',
             '<img src="img8.png" height="52"></img>',
             '<img src="img9.png" height="52"></img>'),
      Actions = shinyInput(actionButton, 12, 'button_', label = "Linked to", onclick = 'Shiny.onInputChange(\"select_button\",  this.id)' ),
      stringsAsFactors = FALSE,
      row.names = 1:12
    ))
    
    
    output$data <- DT::renderDataTable(
      df$data, server = FALSE, escape = FALSE, selection = 'none'
    )

...

This should be the only part of the code that is relevant (other tabs are not included, as well as server code), so don't mind if some parentheses is missing or something like that. I would simply like to have a proper way of displaying the local images in the column. So, can someone please help me? Thank you in advance!

Upvotes: 0

Views: 561

Answers (1)

St&#233;phane Laurent
St&#233;phane Laurent

Reputation: 84529

Indeed, that doesn't work. This way works, with the images in the www subfolder:

render <- c(
  "function(data, type, row){",
  "  if(type === 'display'){",
  "    var tag = '<img src=\"' + data + '.png\" width=\"100\"/>';",
  "    return tag;",
  "  } else {",
  "    return data;",
  "  }",
  "}"
)

df <- reactiveValues(data = data.frame(
  Name = readUnits$label,
  Icon=c("img1",
         "img1",
         "img2",
         .........),
  Actions = shinyInput(
    actionButton, 12, 'button_', label = "Linked to", onclick = 'Shiny.onInputChange(\"select_button\", this.id)'
  ),
  stringsAsFactors = FALSE,
  row.names = 1:12
))

output$data <- renderDT({
  datatable(
    df$data, 
    selection = 'none',
    options = list(
      columnDefs = list(
        list(targets = 2, render = JS(render))
      )
    )
  )
}, server = FALSE)

Upvotes: 1

Related Questions