Извините за довольно конкретный вопрос, но я довольно новичок в Shiny, и у меня очень много времени, чтобы выяснить, как реактивные элементы перетекают из одной части блестящего приложения в другую и как они подключаются к rhandsontables.
Я пытаюсь рассчитать, отобразить и построить 2 различных спектра источника света с приложением.
Кроме того, я пытаюсь разрешить "настраиваемые" спектры для вставки в rhandsontable и для построения графика.
Позже я сделаю некоторые сравнения между ними, но сейчасЯ просто пытаюсь построить и построить их.
Вот что у меня есть ...
library(shiny)
library(rhandsontable)
library(colorSpec)
# Spectra Types
spectra.types = list(
"CIE D50" = 0,
"CIE D55" = 1,
"CIE D65" = 2,
"CIE D75" = 3,
"Custom CIE Daylight" = 4,
"CIE A" = 5,
"Custom Planckian (Blackbody)" = 6,
"Custom SPD" = 7)
ui <- fluidPage(
# Use ShinyJS
shinyjs::useShinyjs(),
# Application title
titlePanel("Spectra Calculator"),
br(),
# Sidebar
fluidRow(
column(12,
tabsetPanel(type = "tabs",
tabPanel("Reference Spectra", label = "Reference Spectra",
br(),
# Dropdown Menu
column(3,
selectInput("spec.type.ref", label = "Spectra Type",
choices = spectra.types,
selected = 0),
# Inputs for CCT and Wavelength
numericInput("cct.ref", label = "CCT", value = 5000),
numericInput("minWl.ref", label = "Minimum Wavelength", value = 300),
numericInput("maxWl.ref", label = "Maximum Wavelength", value = 830),
numericInput("incWl.ref", label = "Wavelength Increments", value = 2)
),
# Table
column(2,
rHandsontableOutput('spec.table.ref'),
br()
),
column(7,
plotOutput('plot.ref')
)
),
tabPanel("Test Spectra", label = "Test Spectra",
br(),
# Dropdown Menu
column(3,
selectInput("spec.type.test", label = "Spectra Type",
choices = spectra.types,
selected = 0),
# Inputs for CCT and Wavelength
numericInput("cct.test", label = "CCT", value = 5000),
numericInput("minWl.test", label = "Minimum Wavelength", value = 300),
numericInput("maxWl.test", label = "Maximum Wavelength", value = 830),
numericInput("incWl.test", label = "Wavelength Increments", value = 2),
actionButton("reset.test", "Reset Custom Test Data Table")
),
# Table
column(2,
rHandsontableOutput('spec.table.test'),
br()
),
column(7,
plotOutput('plot.test')
)
)
)
)
)
)
server <- function(input,output,session)({
# Show or Hide Widgets based on Dropdown Selection
observe({
if (input$spec.type.ref == 4 || input$spec.type.ref == 6 ) {
shinyjs::show("cct.ref")
} else {
shinyjs::hide("cct.ref")
}
})
observe({
if (input$spec.type.test == 4 || input$spec.type.test == 6 ) {
shinyjs::show("cct.test")
} else {
shinyjs::hide("cct.test")
}
})
observe({
if (input$spec.type.test == 7) {
shinyjs::show("reset.test")
} else {
shinyjs::hide("reset.test")
}
})
wl.ref <- reactiveValues(data = NULL)
wl.test <- reactiveValues(data = NULL)
spectra.values.ref <- reactiveValues(data = NULL)
spectra.values.test <- reactiveValues(data = NULL)
observe({
wl.ref$data <- seq(input$minWl.ref, input$maxWl.ref, input$incWl.ref)
})
observe({
wl.test$data <- seq(input$minWl.test, input$maxWl.test, input$incWl.test)
})
observe({
cct.ref <- get_choice_cct(input$spec.type.ref, input$cct.ref)
spectra.values.ref$data <- generate_spectra(input$spec.type.ref, wl.ref$data, cct.ref)
})
observe({
cct.test <- get_choice_cct(input$spec.type.test, input$cct.test)
spectra.values.test$data <- generate_spectra(input$spec.type.test, wl.test$data, cct.test)
})
observe({
if(!is.null(input$spec.table.test)) {
data <- hot_to_r(input$spec.table.test)
spectra.values.test$data <- colorSpec(data,
wl.test$data,
quantity = "auto",
organization = "auto")
}
})
observe({
if(!is.null(input$spec.table.ref)) {
data <- hot_to_r(input$spec.table.ref)
spectra.values.ref$data <- colorSpec(data,
wl.ref$data,
quantity = "auto",
organization = "auto")
}
})
# Subfunctions
get_choice_cct <- function(spec.choice, cct) {
switch(spec.choice,
"0" = {cct <- 5000},
"1" = {cct <- 5500},
"2" = {cct <- 6500},
"3" = {cct <- 7500},
"4" = {cct <- cct},
"5" = {cct <- 2848},
"6" = {cct <- cct},
"7" = {cct <- NULL})
return(cct)
}
generate_spectra <- function(spec.choice, wl, cct) {
# Generate spectr depending on choice
# For choices 0 through 4
if (spec.choice >= 0 && spec.choice <= 4) {
if (cct < 4000) {
stop("D-Illuminants are not defined for CCT <4000K")
}
if (cct > 25000) {
stop("D-Illuminants are not defined for CCT >25000K")
}
# Specify c2 correction factor
c2_correction <- 14388 / 14380
# Generate daylight spectra
if (spec.choice == 4) {
# For custom spectra
spectra <- daylightSpectra(cct,
wavelength = wl,
roundMs = TRUE )
} else {
# For a CIE canonical daylight
spectra <- daylightSpectra(cct * c2_correction,
wavelength = wl,
roundMs = TRUE )
}
} else if (spec.choice == 5) {
# For Iluminant A
spectra = planckSpectra(cct,
wavelength = wl,
c2=1.435e7)
} else if (spec.choice == 6) {
# For custom planckian spectra
spectra <- planckSpectra(cct,
normalize=TRUE,
wavelength = wl)
} else if (spec.choice == 7) {
# For custom spectra
spectra <- illuminantE( energy = 0,
wavelength = wl)
organization(spectra) <- 'matrix'
}
return(spectra)
}
# Output Functions
output$plot.test <- renderPlot({
plot(spectra.values.test$data,
color='black',
main='Test Spectra')
})
output$plot.ref <- renderPlot({
plot(spectra.values.ref$data,
color='black',
main='Reference Spectra')
})
output$spec.table.test <- renderRHandsontable({
rhandsontable(spectra.values.test$data,
colHeaders='Relative Spectral Power',
rowHeaders=wl.test$data,
digits = 10) %>%
hot_col(1, format = '0.0000000000')
})
output$spec.table.ref <- renderRHandsontable({
rhandsontable(spectra.values.ref$data,
colHeaders='Relative Spectral Power',
rowHeaders=wl.ref$data,
digits = 10) %>%
hot_col(1, format = '0.0000000000')
})
})
shinyApp(ui = ui, server = server)
Проблемы, с которыми я сейчас сталкиваюсь, заключаются в том, что
1) Когда я сжимаю данные таблицы в объект colorSpec
и пытаюсь изменить длину волны min, max или инкременты, я получаю сообщение об ошибке из-за того, что компоненты, используемые для построения объекта colorSpec
, не имеют одинаковую длину.Это не имеет смысла для меня, так как у меня есть observe
элементы, проверяющие эти элементы на предмет изменений.Кроме того, это работает, если я не пытаюсь построить объект colorSpec
, но это вызывает другие проблемы с построением графиков.
2) Кажется, что мой rhandsontable
работает только тогда, когда значения, введенные в таблицу, являются целыми числами.
Буду признателен за любые мысли.