Блестящее веб-приложение, использующее Rhandsontable - PullRequest
0 голосов
/ 03 октября 2018

Извините за довольно конкретный вопрос, но я довольно новичок в 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 работает только тогда, когда значения, введенные в таблицу, являются целыми числами.

Буду признателен за любые мысли.

...