Skip to content

Commit

Permalink
133 take 2@filter panel refactor@main (#268)
Browse files Browse the repository at this point in the history
Adds a numeric range input to range filter state cards so range can be
set manually. This is a redo of #226


Fixes #133
  • Loading branch information
asbates authored May 9, 2023
1 parent 7465005 commit cb82947
Show file tree
Hide file tree
Showing 2 changed files with 147 additions and 11 deletions.
153 changes: 142 additions & 11 deletions R/FilterStateRange.R
Original file line number Diff line number Diff line change
Expand Up @@ -393,16 +393,46 @@ RangeFilterState <- R6::R6Class( # nolint
# id of shiny element
ui_inputs = function(id) {
ns <- NS(id)
div(
class = "choices_state",
div(
class = "filterPlotOverlayRange",
plotOutput(ns("plot"), height = "100%"),

tagList(
shinyWidgets::switchInput(
ns("manual"),
label = "Enter manually",
size = "small",
labelWidth = "100px",
onLabel = "Yes",
offLabel = "No",
onStatus = "info",
offStatus = "info"
),
div(
class = "filterRangeSlider",
teal.widgets::optionalSliderInput(
inputId = ns("selection"),
conditionalPanel(
ns = ns,
condition = "input.manual === false",
div(
class = "choices_state",
div(
class = "filterPlotOverlayRange",
plotOutput(ns("plot"), height = "100%"),
),
div(
class = "filterRangeSlider",
teal.widgets::optionalSliderInput(
inputId = ns("selection"),
label = NULL,
min = private$choices[1L],
max = private$choices[2L],
value = shiny::isolate(private$selected()),
step = private$slider_step,
width = "100%"
)
)
)
),
conditionalPanel(
ns = ns,
condition = "input.manual === true",
shinyWidgets::numericRangeInput(
inputId = ns("selection_manual"),
label = NULL,
min = private$choices[1L],
max = private$choices[2L],
Expand All @@ -411,8 +441,11 @@ RangeFilterState <- R6::R6Class( # nolint
width = "100%"
)
),
private$keep_inf_ui(ns("keep_inf")),
private$keep_na_ui(ns("keep_na"))
div(
class = "filter-card-body-keep-na-inf",
private$keep_inf_ui(ns("keep_inf")),
private$keep_na_ui(ns("keep_na"))
)
)
},

Expand Down Expand Up @@ -493,6 +526,74 @@ RangeFilterState <- R6::R6Class( # nolint
}
}
)

private$observers$selection_manual <- observeEvent(
ignoreNULL = FALSE,
ignoreInit = TRUE,
eventExpr = input$selection_manual,
handlerExpr = {
# 3 separate checks are required here to prevent errors
#
# if the user sets either input to 'e' it will return NA
# this NA would cause the lower > upper check to return NA
# and the if(lower > upper) check would throw an error
#
# if lower > manual, contain_interval() will error because it
# expects it's input to be sorted
if (any(is.na(input$selection_manual))) {
showNotification(
"Numeric range values must be numbers.",
type = "warning"
)
shinyWidgets::updateNumericRangeInput(
session = session,
inputId = "selection_manual",
value = private$get_selected()
)
return(NULL)
}
if (input$selection_manual[1] > input$selection_manual[2]) {
showNotification(
"Numeric range start value must be less than end value.",
type = "warning"
)
shinyWidgets::updateNumericRangeInput(
session = session,
inputId = "selection_manual",
value = private$get_selected()
)
return(NULL)
}
# all.equal not enough here b/c tolerance
# all.equal(0.000000001, 0) is TRUE
out_of_range <- isFALSE(identical(
input$selection_manual,
contain_interval(input$selection_manual, private$slider_ticks)
))
if (out_of_range) {
showNotification(
"Numeric range values should correspond to slider values.",
type = "warning"
)
shinyWidgets::updateNumericRangeInput(
session = session,
inputId = "selection_manual",
value = private$get_selected()
)
return(NULL)
}
logger::log_trace(
sprintf(
"RangeFilterState$server@3 selection of variable %s changed, dataname: %s",
private$varname,
private$dataname
)
)
if (!isTRUE(all.equal(input$selection_manual, private$get_selected()))) {
private$set_selected(input$selection_manual)
}
}
)

private$keep_inf_srv("keep_inf")
private$keep_na_srv("keep_na")
Expand All @@ -502,6 +603,10 @@ RangeFilterState <- R6::R6Class( # nolint
id = "selection",
condition = !private$is_disabled()
)
shinyjs::toggleState(
id = "selection_manual",
condition = !private$is_disabled()
)
shinyjs::toggleState(
id = "keep_na-value",
condition = !private$is_disabled()
Expand All @@ -510,7 +615,33 @@ RangeFilterState <- R6::R6Class( # nolint
id = "keep_inf-value",
condition = !private$is_disabled()
)
shinyWidgets::updateSwitchInput(
session = session,
inputId = "manual",
disabled = private$is_disabled()
)
})

observeEvent(input$manual,
{
if (input$manual) {
private$set_selected(input$selection)
shinyWidgets::updateNumericRangeInput(
session = session,
inputId = "selection_manual",
value = input$selection
)
} else {
private$set_selected(input$selection_manual)
updateSliderInput(
session = session,
inputId = "selection",
value = input$selection_manual
)
}
},
ignoreInit = TRUE
)

logger::log_trace("RangeFilterState$server initialized, dataname: { private$dataname }")
NULL
Expand Down
5 changes: 5 additions & 0 deletions inst/css/filter-panel.css
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,11 @@ a.remove_all:hover {
padding: 5px 10px;
}

.filter-card-body-keep-na-inf {
display: flex;
justify-content: space-evenly;
}

.progress.state-count-container {
height: 1.75em;
width: 90%;
Expand Down

0 comments on commit cb82947

Please sign in to comment.