2
votes

It's a bit open-minded. I did some research with google, but no hit at all.

I have a shiny project, in which I use a checkboxGroupInput in sidepanel, sth like this:

   checkboxGroupInput("variable", "Variable:",
                     choices = names ,selected = names
    )

where the 'names' is a character vector.

I include legend (different colors for different names) in a chart in main panel. Now I am thinking to change the text colors of the names (one color for each name) in sidepanel so that I can get rid of the legend in the chart.

Does anyone know how to do it? thanks so much.

3
You should try to avoid using existing R function names like names to store your content. Prefer using my_names instead. - HubertL
Thanks for reminding. This is not my code, I just copied a simpler code as an example. Would you please take a look at my question posted under your answer? Thanks - user2767152

3 Answers

2
votes

You can not do this directly in shiny, BUT you can analyse the HTML built by shiny in the browser inspector/

<div id="variable" class="form-group shiny-input-checkboxgroup shiny-input-container">
  <label class="control-label" for="variable">Variable:</label>
  <div class="shiny-options-group">
    <div class="checkbox">
      <label>
        <input type="checkbox" name="variable" value="1" checked="checked"/>
        <span>one</span>
      </label>
    </div>
    <div class="checkbox">
      <label>
        <input type="checkbox" name="variable" value="2" checked="checked"/>
        <span>two</span>
      </label>
    </div>
    <div class="checkbox">
      <label>
        <input type="checkbox" name="variable" value="3"/>
        <span>three</span>
      </label>
    </div>
  </div>
</div>

you can then recreate it using renderUI:

my_checkboxGroupInput <- function(variable, label, choices, selected, colors){
  choices_names <- choices
  if(length(names(choices))>0) my_names <- names(choices)
  div(id=variable,class="form-group shiny-input-checkboxgroup shiny-input-container shiny-bound-input",
    HTML(paste0('<label class="control-label" for="',variable,'">',label,'</label>')),
    div( class="shiny-options-group",
      HTML(paste0('<div class="checkbox" style="color:', colors,'">',
                    '<label>',
                    '<input type="checkbox" name="', variable, 
                        '" value="', choices, 
                        '"', ifelse(choices %in% selected, 'checked="checked"', ''), 
                    '/>',
                    '<span>', choices_names,'</span>',
                    '</label>',
                  '</div>', collapse = " "))
      )
    )
}

library(shiny)
my_names <- c('one'=1,'two'=2,'three'=3)
my_selected <- c(1,2)
my_colors <-c('blue','red','green')
shinyApp(
  ui=fluidPage(uiOutput("my_cbgi")),
  server = function(input, output, session) {
    output$my_cbgi <- renderUI(my_checkboxGroupInput("variable", "Variable:",
                                                     choices = my_names,
                                                     selected=my_selected, 
                                                     colors=my_colors))
    }
  )

Edit

In order to display in color only selected items, you need to slightly modify the function and use a reactiveValue to map input$variable as the current selection, like this:

my_checkboxGroupInput <- function(variable, label,choices, selected, colors){
  my_names <- choices
  if(length(names(choices))>0) my_names <- names(choices)
  div(id=variable,class="form-group shiny-input-checkboxgroup shiny-input-container shiny-bound-input",
    HTML(paste0('<label class="control-label" for="',variable,'">',label,'</label>')),
    div( class="shiny-options-group",
      HTML(paste0('<div class="checkbox">',
                    '<label>',
                    '<input type="checkbox" name="', variable, 
                        '" value="', choices, 
                        '"', ifelse(choices %in% selected, 'checked="checked"', ''), 
                    '/>',
                    '<span ', ifelse(choices %in% selected, paste0('style="color:', colors,'"'),''), '>',my_names,'</span>',
                    '</label>',
                  '</div>', collapse = " "))
      )
    )
}

my_names <- c('one'=1,'two'=2,'three'=3)
my_selected <- c(1,2)
my_colors <-c('blue','red','green')
shinyApp(ui=fluidPage(uiOutput("my_cbgi")),
         server = function(input, output, session) {
           my <- reactiveValues(selected=my_selected)
           observeEvent(input$variable,{my$selected <- input$variable})
           output$my_cbgi <- renderUI(my_checkboxGroupInput("variable", "Variable:",
                                                            choices = my_names, 
                                                            selected=my$selected,
                                                            colors=my_colors))
         })
1
votes

You could use tags$style for that:

lapply(1:length(names), function(x) {
   n <- length(names)
   col <- gplots::col2hex(rainbow(n)[x])
   css_col <- paste0("#variable div.checkbox:nth-child(",x,
                     ") span{color: ", col,";}")
   tags$style(type="text/css", css_col)
}),
checkboxGroupInput("variable", "Variable:",
                   choices = names, selected = names)
0
votes

@HubertL

Your final version works great. However, I wanna things more dynamic -- instead of assigning a color to a choice permanently, I prefer assigning first N colors to the N chosen item. Unfortunately, the code I customized does not work the way I want.

For example, I have 6 colors, and have all six variables chosen by default, when I de-check any one of (two, three, four, five), I assume the color ones after the de-checked will update properly. let's say ('blue','red','green','purple','lemon','brown') for ('one','two','three','four','five','six'); when I de-check 'three', I wanna see ('blue','red','green','purple','lemon') for ('one','two','four','five','six'), but the actual color is ('blue','red','purple','lemon','blue').

here is the code I used for testing:

my_names <- c('one','two','three','four','five','six')

my_selected <- c('one','two','three','four','five','six')

my_colors <-c('blue','red','green','purple','lemon','brown')

shinyApp(ui=fluidPage(uiOutput("my_cbgi")),

     server = function(input, output, session) {
       my <- reactiveValues(selected=my_selected)
       observeEvent(input$variable,{my$selected <- input$variable})
       output$my_cbgi <- renderUI(my_checkboxGroupInput("variable", "Variable:",
                                                        choices = my_names, 
                                                        selected=my$selected,
                                                        colors=my_colors[1:length(my$selected)]))
     })