Propose of pcrPlateInput shiny control is to view runs as a PCR plate like any conventional real-time PCR software:
library(shinyMolBio)
library(tidyverse)
library(RDML)
# load RDML file
rdml <- RDML$new(system.file("/extdata/stepone_std.rdml", package = "RDML"))
# create Shiny control
pcrPlateInput(inputId = "firstLook", # Shiny input ID
label = "Example", # optional plate label
plateDescription = rdml$AsTable(), # plate description (wells content)
interactive = FALSE
)
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
A | NTC_RNase P | NTC_RNase P | NTC_RNase P | pop1_RNase P | pop1_RNase P | pop1_RNase P | pop2_RNase P | pop2_RNase P | ||||
B | pop2_RNase P | STD_RNase P_10000.0 | STD_RNase P_10000.0 | STD_RNase P_10000.0 | STD_RNase P_5000.0 | STD_RNase P_5000.0 | STD_RNase P_5000.0 | STD_RNase P_2500.0 | ||||
C | STD_RNase P_2500.0 | STD_RNase P_2500.0 | STD_RNase P_1250.0 | STD_RNase P_1250.0 | STD_RNase P_1250.0 | STD_RNase P_625.0 | STD_RNase P_625.0 | STD_RNase P_625.0 | ||||
D | ||||||||||||
E | ||||||||||||
F | ||||||||||||
G | ||||||||||||
H |
PCR plate is fully customizable and can be interactive - selectable wells.
There are several parameters that can be changed:
Some PCR plate wells can be marked as selected by
selection = c(TO_SELECT)
(TO_SELECT
can be
position or react.id)
pcrPlateInput(inputId = "testPlateSel",
label = "Selection",
plateDescription = rdml$AsTable(),
selection = 1:12, # optional preselected wells
interactive = FALSE
)
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
A | NTC_RNase P | NTC_RNase P | NTC_RNase P | pop1_RNase P | pop1_RNase P | pop1_RNase P | pop2_RNase P | pop2_RNase P | ||||
B | pop2_RNase P | STD_RNase P_10000.0 | STD_RNase P_10000.0 | STD_RNase P_10000.0 | STD_RNase P_5000.0 | STD_RNase P_5000.0 | STD_RNase P_5000.0 | STD_RNase P_2500.0 | ||||
C | STD_RNase P_2500.0 | STD_RNase P_2500.0 | STD_RNase P_1250.0 | STD_RNase P_1250.0 | STD_RNase P_1250.0 | STD_RNase P_625.0 | STD_RNase P_625.0 | STD_RNase P_625.0 | ||||
D | ||||||||||||
E | ||||||||||||
F | ||||||||||||
G | ||||||||||||
H |
Some PCR plate wells can be marked as highlighted by
highlightning = c(TO_HIGHLIGHT)
(TO_HIGHLIGHT
can be position or react.id)
pcrPlateInput(inputId = "testPlateHl",
label = "Highlight",
plateDescription = rdml$AsTable(),
selection = 1:12, # optional preselected wells
highlighting = 3:6, # optional highlighted wells
interactive = FALSE
)
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
A | NTC_RNase P | NTC_RNase P | NTC_RNase P | pop1_RNase P | pop1_RNase P | pop1_RNase P | pop2_RNase P | pop2_RNase P | ||||
B | pop2_RNase P | STD_RNase P_10000.0 | STD_RNase P_10000.0 | STD_RNase P_10000.0 | STD_RNase P_5000.0 | STD_RNase P_5000.0 | STD_RNase P_5000.0 | STD_RNase P_2500.0 | ||||
C | STD_RNase P_2500.0 | STD_RNase P_2500.0 | STD_RNase P_1250.0 | STD_RNase P_1250.0 | STD_RNase P_1250.0 | STD_RNase P_625.0 | STD_RNase P_625.0 | STD_RNase P_625.0 | ||||
D | ||||||||||||
E | ||||||||||||
F | ||||||||||||
G | ||||||||||||
H |
All visualion of PCR plate can be modified by custom CSS. This CSS can be loaded as file or as text and can be global or plate instance specific.
Description of the default CSS file:
/* Global plate style */
-plate-tbl{
table.pcr: 100%;
width-collapse: separate;
border-spacing: 1px;
border
}/* Global plate style */
-plate-tbl td, table.pcr-plate-tbl th{
table.pcr: 4rem;
width: 2rem;
height: 2px solid #ccc;
border-align: center;
text
}/* Plate well style */
-plate-tbl td{
table.pcr-width: 4rem;
max-wrap: break-word;
word
}/* Plate header */
-plate-tbl th{
table.pcr-color: white;
border: white;
color
}/* Plate header even column*/
-plate-tbl thead th:nth-child(even){
table.pcr-color: #3CA9E8;
background
}/* Plate header odd column */
-plate-tbl thead th:nth-child(odd){
table.pcr-color: #178ACC;
background
}/* Plate header odd row */
-row{
th.odd-color: #3CA9E8;
background
}/* Plate header even row */
-row{
th.even-color: #178ACC;
background
}/* Selected well */
-well{
td.selected: 2px solid black !important;
border
}/* Toggle all sign */
-all {
th.toggle: transparent !important;
background: relative;
position
}/* Toggle all sign */
-all:after {
th.toggle: "";
content: absolute;
position: 0;
bottom: 0;
right: 0;
width: 0;
height: block;
display-left: 1em solid transparent;
border-bottom: 1em solid transparent;
border-bottom: 1em solid grey;
border }
So if you want to set your own style of plate you can do it by:
cssFile = YOUR_FILE
cssFile = "", cssText = YOUR_TEXT
cssText = YOUR_TEXT
Note that inside Shiny app CSS loads as singleton (once for all
plates) but in Rmd file it loads for every plate but
works globally too - you can prevent such loading by setting
cssFile = ""
To make CSS rule only for current plate add #{{id}}
before CSS rule. For example if you want set selection border to red and
well color to light green
pcrPlateInput(inputId = "customCSS", # Shiny input ID
label = "Custom CSS: red selection and light green plate background",
plateDescription = rdml$AsTable(),
selection = c("A01", "C08"), # optional preselected wells
cssFile = "",
cssText = "#{{id}} td.selected-well{border: 2px solid red !important;}
#{{id}} table.pcr-plate-tbl td{background-color: #ebffe0;}
",
interactive = FALSE
)
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
A | NTC_RNase P | NTC_RNase P | NTC_RNase P | pop1_RNase P | pop1_RNase P | pop1_RNase P | pop2_RNase P | pop2_RNase P | ||||
B | pop2_RNase P | STD_RNase P_10000.0 | STD_RNase P_10000.0 | STD_RNase P_10000.0 | STD_RNase P_5000.0 | STD_RNase P_5000.0 | STD_RNase P_5000.0 | STD_RNase P_2500.0 | ||||
C | STD_RNase P_2500.0 | STD_RNase P_2500.0 | STD_RNase P_1250.0 | STD_RNase P_1250.0 | STD_RNase P_1250.0 | STD_RNase P_625.0 | STD_RNase P_625.0 | STD_RNase P_625.0 | ||||
D | ||||||||||||
E | ||||||||||||
F | ||||||||||||
G | ||||||||||||
H |
Well label, on hover text and other marks can be setted by templates.
To do this pcrPlateInput use whisker
package - so you can provide column names of plate description as
shortcuts inside templates {{COLUMN}}
(or
{{{COLUMN}}}
- without escaping basic HTML characters).
wellLabelTemplate = "{{sample}}"
- text inside well
(label)onHoverWellTextTemplate = "{{position}}\u000A{{sample}}\u000A{{target}}"
- on hover textwellClassTemplate = NULL
- specific class for current
wellwellStyleTemplate = NULL
- specific CSS style for
current wellFor example we want to show sample name, Cq and
Cq < 30 or Cq > 35 with colored circle as label;
target name and dye as on hover text; mark sample
type with border color by class; set different background color for
each sample name. Also legend will be added by
legend = YOUR_HTML_LEGEND
.
Note: if your plate description contains several rows with the same
position - only the first will be used! So for example to print all
targets for one well combine them to the new column like this
tbl %>% group_by(position) %>% mutate(targets = paste(target, collapse = ", "))
.
##
## Attaching package: 'shiny'
## The following object is masked from 'package:shinyMolBio':
##
## runExample
plateDescription <- rdml$AsTable(cq = round(data$cq)) %>%
group_by(fdata.name) %>%
mutate(sampleType = sample.type, # whisker does not support dots!
dyeId = target.dyeId, # whisker does not support dots!
mark = {
if (cq < 30) "<span class='filled-circle1'></span>"
else if (cq > 35) "<span class='filled-circle2'></span>"
else ""
})
uniqSamples <- unique(plateDescription$sample)
sampleColors <- topo.colors(length(uniqSamples), alpha = 0.3)
names(sampleColors) <- uniqSamples
plateDescription <- plateDescription %>%
group_by(sample) %>%
mutate(color = sampleColors[sample] %>%
col2rgb() %>%
.[,1] %>% c(0.2) %>%
paste(collapse = ","))
pcrPlateInput("customLabel", "Custom labels and marks",
plateDescription,
wellLabelTemplate = "{{{mark}}}{{sample}} Cq={{cq}}",
onHoverWellTextTemplate = "{{target}}: {{dyeId}}",
wellClassTemplate = "{{sampleType}}",
wellStyleTemplate = "background-color:rgba({{color}});",
cssFile = "",
cssText = "#{{id}} td.selected-well{border: 2px solid red !important;}
#{{id}} .ntc{border: 3px solid Plum;}
#{{id}} .unkn{border: 3px solid Salmon;}
#{{id}} .pos{border: 3px solid PaleGreen ;}
#{{id}} .neg{border: 3px solid LightGrey ;}
#{{id}} .std{border: 3px solid DeepSkyBlue ;}
#{{id}} .filled-circle1 {padding: 2px 11px;
border-radius: 100%; background-color: Maroon;}
#{{id}} .filled-circle2 {padding: 2px 11px;
border-radius: 100%; background-color: Orange;}",
legend =
tags$div(
tags$span(class = "filled-circle1"), "Cq < 30",
tags$br(),
tags$span(class = "filled-circle2"), "Cq > 35",
tags$br(),
tags$span(
tags$span(class = "ntc", "NTC"),
tags$span(class = "unkn", "Unknown"),
tags$span(class = "pos", "Positive"),
tags$span(class = "neg", "Negative"),
tags$span(class = "std", "Standard")
)
),
interactive = FALSE
)
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
A | NTC_RNase P Cq=40 | NTC_RNase P Cq=40 | NTC_RNase P Cq=40 | pop1_RNase P Cq=29 | pop1_RNase P Cq=29 | pop1_RNase P Cq=29 | pop2_RNase P Cq=28 | pop2_RNase P Cq=28 | ||||
B | pop2_RNase P Cq=28 | STD_RNase P_10000.0 Cq=27 | STD_RNase P_10000.0 Cq=27 | STD_RNase P_10000.0 Cq=27 | STD_RNase P_5000.0 Cq=28 | STD_RNase P_5000.0 Cq=28 | STD_RNase P_5000.0 Cq=28 | STD_RNase P_2500.0 Cq=29 | ||||
C | STD_RNase P_2500.0 Cq=29 | STD_RNase P_2500.0 Cq=29 | STD_RNase P_1250.0 Cq=30 | STD_RNase P_1250.0 Cq=30 | STD_RNase P_1250.0 Cq=30 | STD_RNase P_625.0 Cq=31 | STD_RNase P_625.0 Cq=31 | STD_RNase P_625.0 Cq=31 | ||||
D | ||||||||||||
E | ||||||||||||
F | ||||||||||||
G | ||||||||||||
H |
Run shinyMolBio::runExample("pcrPlateInput")
to see
interactive PCR plate in action. This demo Shiny App
allows you to open PCR plate via RDML package and view
in two independent plates: one with default style and second with
custom. You can click on wells and see which of them are selected after
that. Available click targets are:
wellGroupTemplate
Also this app shows action of updatePcrPlateInput
function. Clicking on Select Random Well button selects well on
the second plate.