xlai / dosefinderhub

A comprehensive hub for the design, conduct, and comparison of dose-finding methods in Phase 1 clinical trials.
GNU General Public License v3.0
0 stars 0 forks source link

Improving the questionnaire UIs #20

Open sdennett20 opened 1 year ago

sdennett20 commented 1 year ago

Is your feature request related to a problem? Please describe. Further enhancements to the questionnaire UIs are planned to make it more user-friendly and more future-proof for the introduction of other trial designs. Currently:

Describe the solution you'd like

  1. We want the questions to appear one at a time, maybe with a progress bar to track the user's progress through the questionnaires. There also needs to be some conditional sequencing of the questions, so that only some questions appear depending on the answer of a previous question.
  2. Add outcome descriptions and explanations to aid the user experience. 'Flashcard'/tiles are a good place to do this, or a tooltip style approach may work.
  3. Create a function that calls only the design, the q_database which will generate the relevant method-specific questionnaire, according to the vector of recommended designs.
xlai commented 1 year ago

@sdennett20 would you like me to help on any of the specific tasks?

sdennett20 commented 1 year ago

I should be able to have a go this week at Task 1 but I'll let you know of any issues I encounter. Regarding Task 2, I feel some more expertise knowledge than I can provide may be needed. Perhaps we can have a look at the code you have for actually creating the flashcards in the UI and then I can work on adding descriptions to the flashcards but with your (or someone else's) opinions and insight on specifics of each design. Maybe we can also discuss with Christina.

xlai commented 1 year ago
1. We want the questions to appear one at a time, maybe with a progress bar to track the user's progress through the questionnaires. There also needs to be some conditional sequencing of the questions, so that only some questions appear depending on the answer of a previous question.

I'm happy to provide example code for the implementation of progress bar if you would like?

2. Add outcome descriptions and explanations to aid the user experience. 'Flashcard'/tiles are a good place to do this, or a tooltip style approach may work.

If we need tooltip, then it means we need to modify the questionnaire database again to include additional column called 'hint'. Happy to discuss.

3. Create a function that calls only the design, the q_database which will generate the relevant method-specific questionnaire, according to the vector of recommended designs.

As we discussed in #11, we will skip the recommendation for now and work on honing the UI. You can leave this part to me.

sdennett20 commented 1 year ago

Yes please to the above!

I don't know much about the alternative options to using a tooltip but I'm sure there are several. Jake had brought them up a few times but happy to consider other things.

xlai commented 1 year ago
ui <- shiny::fluidPage(
  theme = bslib::bs_theme(bootswatch = "darkly"),
  shiny::titlePanel("Welcome to the Dose Finder Hub!"),
  shiny::mainPanel(
    shiny::h4("Please answer the questions below to get 
       recommended trial designs tailored to your
       needs, or upload previously saved responses."),
    shiny::fileInput("file_upload", "Upload Previous Responses:",
                     accept = c(".csv", ".rds")),
    shiny::uiOutput("questionsUI"),
    # Progress bar
    tags$hr(),
    shiny::textOutput("progress"),
    # Next button
    shiny::actionButton("next_button", "Next"),
    shiny::fluidRow(
      shiny::actionButton("get_rating",
                          label = "Generate recommendations!",
                          width = 500)
    )
  ),
  shiny::textOutput("recommendations"),
  shiny::downloadButton("save_button", "Save Responses")
)

The additional progress bar and Next button are added to the UI.

server <- function(input, output, session) {
  # ... (your existing code for loading questions and parsing params)

  # Reactive variable to keep track of the current question
  current_question <- reactiveVal(1)

  # Update the current question in the UI
  output$questionsUI <- renderUI({
    current_q <- current_question()
    if (current_q <= nrow(questions)) {
      question <- questions[questions$q_number == current_q, ]
      params <- parse_params(question$params)
      switch(question$q_type,
             radioButtons = shiny::radioButtons(inputId = question$q_variable,
                                                label = question$q_text,
                                                choices = strsplit(params[["choices"]], ",")[[1]],
                                                width = 500),
             numeric = shiny::numericInput(inputId = question$q_variable,
                                           label = question$q_text,
                                           min = as.numeric(params[["min"]]),
                                           value = 0,
                                           width = 500),
             slider = shiny::sliderInput(inputId = question$q_variable,
                                         label = question$q_text,
                                         min = as.numeric(params[["min"]]),
                                         max = as.numeric(params[["max"]]),
                                         value = as.numeric(params[["min"]]),
                                         width = 500),
             text = shiny::textInput(inputId = question$q_variable,
                                     label = question$q_text,
                                     placeholder = "Enter your hint here",
                                     value = "", width = 500)
      )
    }
  })

  # Update the progress bar
  output$progress <- renderText({
    paste("Progress:", current_question(), "/", nrow(questions))
  })

  # Update the current question when the next button is clicked
  observeEvent(input$next_button, {
    if (current_question() < nrow(questions)) {
      current_question(current_question() + 1)
    }
  })

  # ... (your existing code for generating recommendations and saving responses)
}

The server file is modified to track the current question and progress is determined as the fraction over total number of questions. A reactive element is also added to observe if the next button was pressed.