Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Icons in data table in Shiny

Tags:

r

icons

shiny

I am trying to add a column of icons to a data table that is shown in a Shiny app. Essentially I just want an up arrow when the data has gone up, and a down arrow when it has gone down. However, I'm not sure how to display an icon. When I add a column just using for e.g. icon("arrow-up"), I get the following error:

Error: default method not implemented for type 'list'

I can see that if I try this approach outside of Shiny, it is displaying the data about the icon rather than displaying the icon.

One option might be to use the approach of adding it as an image - but it feels like there would be a more direct way? I'm also not sure how to do that with Font Awesome icons.

Apologies if this is basic - I couldn't find an answer!

Here is a simplified version of what I'm doing:

library(shiny)
library(shinydashboard)

number_compare <- data.frame(replicate(2, sample(1:100, 10, rep=TRUE)))
number_compare$direction <- ifelse(number_compare$X1 < number_compare$X2, "Up", "Down")
number_compare$direction <- ifelse(number_compare$X1 == number_compare$X2, "", number_compare$direction)


sidebar <- dashboardSidebar()

body <- dashboardBody(
  fluidRow(box(width = 12, solidHeader = TRUE,
               tableOutput("example_table"))
           )
  )

ui <- dashboardPage(dashboardHeader(title = "Example"),
                    sidebar,
                    body
)


server <- function(input, output) {
  output$example_table <- renderTable(number_compare)
}

shinyApp(ui, server)
like image 204
Jaccar Avatar asked Dec 24 '18 15:12

Jaccar


1 Answers

You don't say what icons you want to use, so I will assume angle-up and angle-down from fontawesome, but you can also use glyphicons.

As you point out, the output of icon() is a list. Assigning that in your ifelse would give a column repeating the values i, iconname, and NULL.

Instead, try wrapping icon() in as.character() to give the raw HTML for the icon. E.g:

number_compare$direction <- ifelse(
    number_compare$X1 < number_compare$X2,
    as.character(icon("angle-up")),
    as.character(icon("angle-down"))
)

This will fill the column with values like <i class="fa fa-angle-up"></i> which you can print in the app as raw HTML.

Alternatively, you can use HTML escape codes to print the arrows without using icons. See https://www.w3schools.com/charsets/ref_utf_arrows.asp for a list of HTML escape codes.

Edit: Whenever you include raw HTML in a table, make sure that shiny doesn't escape it. Replace your call to renderTable(number_compare) with renderTable(number_compare, sanitize.text.function = function(x) x) (based on r shiny table not rendering html)

like image 153
anotherfred Avatar answered Sep 28 '22 12:09

anotherfred