Способ не жестко закодировать элементы в css с помощью приложения R Shiny? - PullRequest
1 голос
/ 21 апреля 2020

У меня есть пример кода ниже (взят из здесь ). Есть ли способ для работы ниже, без жесткого кодирования значений "a" и "b" в html css? Если у меня есть сотни предметов, мне не нужно жестко кодировать каждый из них при вызове .option[data-value=a] et c.

shinyApp(
  ui = 
    shinyUI(fluidPage(
      tags$head(
        tags$style(HTML("
        .option[data-value=a], .item[data-value=a]{
          background: red !important;
          color: white !important;
        }
        .option[data-value=b], .item[data-value=b]{
          background: green !important;
          color: white !important;
        }
  "))
      ),
      sidebarLayout(
        sidebarPanel(
          selectizeInput("select", label=NULL,
                         choices=c("a", "b"),
                         selected = c("a", "b"),
                         multiple=TRUE, options=list(placeholder="Wybierz"))),
        mainPanel())
    )
    ),
  server = function(input, output){}
)
> sessionInfo()
R version 3.6.3 (2020-02-29)
Platform: x86_64-apple-darwin15.6.0 (64-bit)
Running under: macOS High Sierra 10.13.6

Matrix products: default
BLAS:   /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/3.6/Resources/lib/libRlapack.dylib

locale:
[1] en_GB.UTF-8/en_GB.UTF-8/en_GB.UTF-8/C/en_GB.UTF-8/en_GB.UTF-8

attached base packages:
[1] stats4    parallel  stats     graphics  grDevices utils     datasets  methods  
[9] base     

other attached packages:
 [1] rsconnect_0.8.16     shinythemes_1.1.2    dplyr_0.8.5          shiny_1.4.0.2       
 [5] BiocParallel_1.20.1  MLInterfaces_1.66.5  cluster_2.1.0        annotate_1.64.0     
 [9] XML_3.99-0.3         AnnotationDbi_1.48.0 IRanges_2.20.2       MSnbase_2.12.0      
[13] ProtGenerics_1.18.0  S4Vectors_0.24.4     mzR_2.20.0           Rcpp_1.0.4.6        
[17] Biobase_2.46.0       BiocGenerics_0.32.0 

1 Ответ

2 голосов
/ 21 апреля 2020

Вы можете написать функцию, которая генерирует код CSS:

CSS <- function(values, colors){
  template <- "
.option[data-value=%s], .item[data-value=%s]{
  background: %s !important;
  color: white !important;
}"
  paste0(
    apply(cbind(values, colors), 1, function(vc){
      sprintf(template, vc[1], vc[1], vc[2])
    }),
    collapse = "\n"
  )
}

Например, CSS(c("a","b","c"), c("red", "green", "blue")) генерирует

.option[data-value=a], .item[data-value=a]{
  background: red !important;
  color: white !important;
}

.option[data-value=b], .item[data-value=b]{
  background: green !important;
  color: white !important;
}

.option[data-value=c], .item[data-value=c]{
  background: blue !important;
  color: white !important;
}

Затем выполните css <- CSS(c("a","b","c"), c("red", "green", "blue")) в начале ваше приложение и выполните tags$style(HTML(css)).

Для многочисленных значений я бы использовал такой код:

library(randomcoloR)

CSS <- function(values){
  template <- "
.option[data-value=%s], .item[data-value=%s]{
  background: %s !important;
  color: %s !important;
}"
  colors <- distinctColorPalette(length(values))
  paste0(
    apply(cbind(values, colors), 1, function(vc){
      rgb <- col2rgb(vc[2])
      color <- 
        ifelse(rgb[1]*0.299 + rgb[2]*0.587 + rgb[3]*0.114 > 186, "black", "white")
      sprintf(template, vc[1], vc[1], vc[2], color)
    }),
    collapse = "\n"
  )
}

css <- CSS(letters[1:10])
.option[data-value=a], .item[data-value=a]{
  background: #DE70C1 !important;
  color: white !important;
}

.option[data-value=b], .item[data-value=b]{
  background: #AE53E3 !important;
  color: white !important;
}

.option[data-value=c], .item[data-value=c]{
  background: #8AE450 !important;
  color: white !important;
}

.option[data-value=d], .item[data-value=d]{
  background: #DD8062 !important;
  color: white !important;
}

.option[data-value=e], .item[data-value=e]{
  background: #D5D063 !important;
  color: black !important;
}

.option[data-value=f], .item[data-value=f]{
  background: #D1B6CD !important;
  color: black !important;
}

.option[data-value=g], .item[data-value=g]{
  background: #8390D3 !important;
  color: white !important;
}

.option[data-value=h], .item[data-value=h]{
  background: #8BD6DC !important;
  color: black !important;
}

.option[data-value=i], .item[data-value=i]{
  background: #80DDA0 !important;
  color: black !important;
}

.option[data-value=j], .item[data-value=j]{
  background: #D2D4AE !important;
  color: black !important;
}

Этот код автоматически устанавливает color в white, если цвет фона темный, и black в противном случае.

...