I have a 96 well plate made from a datatable, with certain cells or rows being colored in, and a radio button that I want to control whether it is the rows or the columns that are colored.
This is what I would like to see if I have the horizontal button selected:
And this is what I would like to see if I have the vertical button selected:
Unfortunately, this is what I see:
The issue that I am having is that once I put in an if statement to change the layout of the selected cells (switching between rows and columns), the colors stopped showing up at all. I'm sure that it's something small that I am missing.
Here is my code:
library(shiny)
library(shinythemes)
library(sortable)
library(colourpicker)
library(glue)
library(png)
library(dplyr)
library(DT)
library(rclipboard)
# funcs
plate96 = function(id) {
div(
style = "position: relative; height: 500px",
tags$style(HTML(
'
.wells {
height: 490px;
width: 750px;
overflow: hidden;
min-height: 20px;
padding: 19px;
margin-bottom: 20px;
border: 1px solid #e3e3e3;
border-radius: 4px;
-webkit-box-shadow: inset 0 1px 1px rgb(0 0 0 / 5%);
box-shadow: inset 0 1px 1px rgb(0 0 0 / 5%);
position: relative;
transform: translateX(50%);
}
.wells:after {
content: "";
height: 450px;
width: 690px;
border: 1px solid;
position: absolute;
transform: translate(15px, -100%);
z-index: -1;
}
.wells .corner-top {
position: absolute;
margin: -20px;
width: 43px;
height: 34px;
transform: rotate(45deg);
background-color: white;
z-index: 1;
left: 30px;
border-right: 1px solid;
}
.wells .corner-bot {
position: absolute;
margin: -20px;
width: 40px;
height: 40px;
transform: rotate(45deg);
background-color: white;
z-index: 1;
left: 35px;
bottom: 20px;
border-top: 1px solid;
}
.wells .html-widget {
transform: translateX(20px);
}
.wells thead tr th {
font-weight: 100;
}
.wells table:after {
content: "";
border: 1px solid #ccc;
position: absolute;
height: 410px;
width: 635px;
z-index: -1;
transform: translate(33px, -99%);
}
.wells table.dataTable.no-footer {
border-spacing: 3px;
border-bottom: unset;
}
.wells table.dataTable thead th {
border-bottom: unset;
}
.wells tbody tr td:not(:first-of-type) {
border-radius: 50%;
border: 1px solid black;
height: 15px;
width: 15px;
padding: 15px;
font-size: 0;
}
.wells table.dataTable.cell-border tbody tr td:first-of-type {
border: unset;
border-right: 1px solid #ccc;
font-weight: 900;
}
'
)),
div(
style = "position: absolute; left: 50%; transform: translateX(-100%);",
div(
class = "wells",
div(class = "corner-top"),
div(class = "corner-bot"),
DT::dataTableOutput(id, width = "90%", height= "100%")
)
)
)
}
renderPlate96 = function(id, colors = rep("white", 96), byrow = TRUE) {
stopifnot(is.character(colors) && length(colors) == 96)
plate = matrix(1:96, nrow = 8, ncol = 12, byrow = byrow, dimnames = list(LETTERS[1:8], 1:12))
colnames(plate) = stringr::str_pad(colnames(plate), 2, "left", "0")
renderDataTable({
datatable(
plate,
options = list(dom = 't', ordering = F),
selection = list(target = 'cell'),
class = 'cell-border compact'
) %>%
formatStyle(
1:12,
cursor = 'pointer',
backgroundColor = styleEqual(1:96, colors, default = NULL)
)
})
}
# app code
ui = fluidPage(
plate96("plate"),
tags$b("Wells Selected:"),
verbatimTextOutput("well_selected"),
####Horizontal vs Vertical orientation radio buttons####
radioButtons("orientation_radio",
label = h3("Horizontal vs Vertical"),
c("Horizontal, counted down rows" = "Horizontal",
"Vertical, counted down columns" = "Vertical")),
)
server = function(input, output, session){
####Outputting the colors for the plates####
output$plate = renderPlate96({
if (input$orientation_radio == "Vertical") {
return("plate",
colors = c(
rep("#eeeeee", 12),
rep("#27408b", 12),
rep("#0f8b44", 12),
rep("#9400d3", 12),
rep("#0701ff", 12),
rep("white", 36)
)
)
}
else if (input$orientation_radio == "Horizontal") {
return("plate",
colors = c(
rep("#eeeeee", 8),
rep("#27408b", 8),
rep("#0f8b44", 8),
rep("#9400d3", 8),
rep("#0701ff", 8),
rep("white", 56)
),
byrow = FALSE
)
}
})
output$well_selected = renderPrint({
input$plate_cells_selected
})
}
shinyApp(ui = ui, server = server)
Can someone please explain to me what I am doing wrong? I am wondering if I am missing a syntax or something. Thanks!
UPDATE By suggestion, I tried both of these approaches, and neither worked, unfortunately.
####Outputting the colors for the plates####
output$plate = renderPlate96({
if (input$orientation_radio == "Vertical") {
renderPlate96("plate",
colors = c(
rep("#eeeeee", 12),
rep("#27408b", 12),
rep("#0f8b44", 12),
rep("#9400d3", 12),
rep("#0701ff", 12),
rep("white", 36)
)
)
}
else if (input$orientation_radio == "Horizontal") {
renderPlate96("plate",
colors = c(
rep("#eeeeee", 8),
rep("#27408b", 8),
rep("#0f8b44", 8),
rep("#9400d3", 8),
rep("#0701ff", 8),
rep("white", 56)
),
byrow = FALSE
)
}
})
####Outputting the colors for the plates####
output$plate = renderPlate96({
if (input$orientation_radio == "Vertical") {
"plate"
colors = c(
rep("#eeeeee", 12),
rep("#27408b", 12),
rep("#0f8b44", 12),
rep("#9400d3", 12),
rep("#0701ff", 12),
rep("white", 36)
)
}
else if (input$orientation_radio == "Horizontal") {
"plate"
colors = c(
rep("#eeeeee", 8),
rep("#27408b", 8),
rep("#0f8b44", 8),
rep("#9400d3", 8),
rep("#0701ff", 8),
rep("white", 56)
)
byrow = FALSE
}
})
I also tried switching renderPlate96 out for just plate
, and that didn't work either... :(
CodePudding user response:
Try this
# funcs
plate96 = function(id) {
div(
style = "position: relative; height: 500px",
tags$style(HTML(
'
.wells {
height: 490px;
width: 750px;
overflow: hidden;
min-height: 20px;
padding: 19px;
margin-bottom: 20px;
border: 1px solid #e3e3e3;
border-radius: 4px;
-webkit-box-shadow: inset 0 1px 1px rgb(0 0 0 / 5%);
box-shadow: inset 0 1px 1px rgb(0 0 0 / 5%);
position: relative;
transform: translateX(50%);
}
.wells:after {
content: "";
height: 450px;
width: 690px;
border: 1px solid;
position: absolute;
transform: translate(15px, -100%);
z-index: -1;
}
.wells .corner-top {
position: absolute;
margin: -20px;
width: 43px;
height: 34px;
transform: rotate(45deg);
background-color: white;
z-index: 1;
left: 30px;
border-right: 1px solid;
}
.wells .corner-bot {
position: absolute;
margin: -20px;
width: 40px;
height: 40px;
transform: rotate(45deg);
background-color: white;
z-index: 1;
left: 35px;
bottom: 20px;
border-top: 1px solid;
}
.wells .html-widget {
transform: translateX(20px);
}
.wells thead tr th {
font-weight: 100;
}
.wells table:after {
content: "";
border: 1px solid #ccc;
position: absolute;
height: 410px;
width: 635px;
z-index: -1;
transform: translate(33px, -99%);
}
.wells table.dataTable.no-footer {
border-spacing: 3px;
border-bottom: unset;
}
.wells table.dataTable thead th {
border-bottom: unset;
}
.wells tbody tr td:not(:first-of-type) {
border-radius: 50%;
border: 1px solid black;
height: 15px;
width: 15px;
padding: 15px;
font-size: 0;
}
.wells table.dataTable.cell-border tbody tr td:first-of-type {
border: unset;
border-right: 1px solid #ccc;
font-weight: 900;
}
'
)),
div(
style = "position: absolute; left: 50%; transform: translateX(-100%);",
div(
class = "wells",
div(class = "corner-top"),
div(class = "corner-bot"),
DTOutput(id, width = "90%", height= "100%")
)
)
)
}
renderPlate96 = function(id, colors = rep("white", 96), byrow = TRUE) {
stopifnot(is.character(colors) && length(colors) == 96)
if (id == "Horizontal") {
colors = c(
rep("#eeeeee", 12),
rep("#27408b", 12),
rep("#0f8b44", 12),
rep("#9400d3", 12),
rep("#0701ff", 12),
rep("white", 36)
)
}else if (id == "Vertical") {
colors = c(
rep("#eeeeee", 8),
rep("#27408b", 8),
rep("#0f8b44", 8),
rep("#9400d3", 8),
rep("#0701ff", 8),
rep("white", 56)
)
byrow = FALSE
}
plate = matrix(1:96, nrow = 8, ncol = 12, byrow = byrow, dimnames = list(LETTERS[1:8], 1:12))
colnames(plate) = stringr::str_pad(colnames(plate), 2, "left", "0")
return( myplate <-
datatable(
plate,
options = list(dom = 't', ordering = F),
selection = list(target = 'cell'),
class = 'cell-border compact'
) %>%
formatStyle(
1:12,
cursor = 'pointer',
backgroundColor = styleEqual(1:96, colors, default = NULL)
)
)
}
# app code
ui = fluidPage(
plate96("plate"),
tags$b("Wells Selected:"),
verbatimTextOutput("well_selected"),
####Horizontal vs Vertical orientation radio buttons####
radioButtons("orientation_radio",
label = h3("Horizontal vs Vertical"),
c("Horizontal, counted down rows" = "Horizontal",
"Vertical, counted down columns" = "Vertical")),
)
server = function(input, output, session){
output$plate <- renderDT({
renderPlate96({as.character(input$orientation_radio)})
})
output$well_selected = renderPrint({
input$plate_cells_selected
})
}
shinyApp(ui = ui, server = server)