Skip to content

Commit a835f3d

Browse files
averissimogithub-actions[bot]gogonzo
authored
545 Keep selected variable in var browser as filters are changed (#549)
# Pull Request Fixes #545 Fixes insightsengineering/teal.gallery#19 #### Changes description - Restores the selection based on the selection _(using variable name instead of indexes)_ - Restores the page _(non-trivial as it needs to calculate the index of the first row in the table)_ #### TODO before ready to review: - [x] Support selection on non-first page rows - uses `displayStart` to set the first row of the page of the selected item --------- Signed-off-by: André Veríssimo <211358+averissimo@users.noreply.github.com> Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Dawid Kałędkowski <6959016+gogonzo@users.noreply.github.com>
1 parent e22210f commit a835f3d

File tree

3 files changed

+101
-81
lines changed

3 files changed

+101
-81
lines changed

NEWS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
* Fixed a bug in `tm_g_scatterplot` when selected x and y facets were the same.
1818
* Fixed a bug in `tm_g_distribution` to plot the theoretical distribution with newer `ggplot2` version.
1919
* Fixed a bug in `tm_g_bivariate` when adding lines checkbox was available if one of x or y was deselected.
20+
* Fixed a bug in `tm_variable_browser` when changing filters would reset the selected variable to the first on the list.
2021

2122
### Miscellaneous
2223

R/tm_variable_browser.R

Lines changed: 96 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1117,7 +1117,8 @@ render_single_tab <- function(dataset_name, parent_dataname, output, data, input
11171117
output = output,
11181118
data = data,
11191119
input = input,
1120-
columns_names = columns_names
1120+
columns_names = columns_names,
1121+
plot_var = plot_var
11211122
)
11221123
}
11231124

@@ -1154,98 +1155,113 @@ render_tab_header <- function(dataset_name, output, data) {
11541155
#' @param parent_dataname (`character`) the name of a parent `dataname` to filter out variables from
11551156
#' @inheritParams render_tabset_panel_content
11561157
#' @keywords internal
1157-
render_tab_table <- function(dataset_name, parent_dataname, output, data, input, columns_names) {
1158+
render_tab_table <- function(dataset_name, parent_dataname, output, data, input, columns_names, plot_var) {
11581159
table_ui_id <- paste0("variable_browser_", dataset_name)
11591160

1160-
output[[table_ui_id]] <- DT::renderDataTable(
1161-
expr = {
1162-
df <- data[[dataset_name]]()
1161+
output[[table_ui_id]] <- DT::renderDataTable({
1162+
df <- data[[dataset_name]]()
11631163

1164-
get_vars_df <- function(input, dataset_name, parent_name, data) {
1165-
data_cols <- colnames(data[[dataset_name]]())
1166-
if (isTRUE(input$show_parent_vars)) {
1167-
data_cols
1168-
} else if (dataset_name != parent_name && parent_name %in% names(data)) {
1169-
setdiff(data_cols, colnames(data[[parent_name]]()))
1170-
} else {
1171-
data_cols
1172-
}
1164+
get_vars_df <- function(input, dataset_name, parent_name, data) {
1165+
data_cols <- colnames(data[[dataset_name]]())
1166+
if (isTRUE(input$show_parent_vars)) {
1167+
data_cols
1168+
} else if (dataset_name != parent_name && parent_name %in% names(data)) {
1169+
setdiff(data_cols, colnames(data[[parent_name]]()))
1170+
} else {
1171+
data_cols
11731172
}
1173+
}
1174+
1175+
if (length(parent_dataname) > 0) {
1176+
df_vars <- get_vars_df(input, dataset_name, parent_dataname, data)
1177+
df <- df[df_vars]
1178+
}
11741179

1175-
if (length(parent_dataname) > 0) {
1176-
df_vars <- get_vars_df(input, dataset_name, parent_dataname, data)
1177-
df <- df[df_vars]
1180+
if (is.null(df) || ncol(df) == 0) {
1181+
columns_names[[dataset_name]] <- character(0)
1182+
df_output <- data.frame(
1183+
Type = character(0),
1184+
Variable = character(0),
1185+
Label = character(0),
1186+
Missings = character(0),
1187+
Sparklines = character(0),
1188+
stringsAsFactors = FALSE
1189+
)
1190+
} else {
1191+
# extract data variable labels
1192+
labels <- teal.data::col_labels(df)
1193+
1194+
columns_names[[dataset_name]] <- names(labels)
1195+
1196+
# calculate number of missing values
1197+
missings <- vapply(
1198+
df,
1199+
var_missings_info,
1200+
FUN.VALUE = character(1),
1201+
USE.NAMES = FALSE
1202+
)
1203+
1204+
# get icons proper for the data types
1205+
icons <- stats::setNames(teal.slice:::variable_types(df), colnames(df))
1206+
1207+
join_keys <- get_join_keys(data)
1208+
if (!is.null(join_keys)) {
1209+
icons[intersect(join_keys$get(dataset_name)[[dataset_name]], colnames(df))] <- "primary_key"
11781210
}
1211+
icons <- variable_type_icons(icons)
1212+
1213+
# generate sparklines
1214+
sparklines_html <- vapply(
1215+
df,
1216+
create_sparklines,
1217+
FUN.VALUE = character(1),
1218+
USE.NAMES = FALSE
1219+
)
11791220

1180-
if (is.null(df) || ncol(df) == 0) {
1181-
columns_names[[dataset_name]] <- character(0)
1182-
data.frame(
1183-
Type = character(0),
1184-
Variable = character(0),
1185-
Label = character(0),
1186-
Missings = character(0),
1187-
Sparklines = character(0),
1188-
stringsAsFactors = FALSE
1189-
)
1190-
} else {
1191-
# extract data variable labels
1192-
labels <- stats::setNames(
1193-
unlist(
1194-
lapply(
1195-
df,
1196-
function(x) {
1197-
`if`(is.null(attr(x, "label")), "", attr(x, "label"))
1198-
}
1199-
)
1200-
),
1201-
names(df)
1202-
)
1221+
df_output <- data.frame(
1222+
Type = icons,
1223+
Variable = names(labels),
1224+
Label = labels,
1225+
Missings = missings,
1226+
Sparklines = sparklines_html,
1227+
stringsAsFactors = FALSE
1228+
)
1229+
}
12031230

1204-
columns_names[[dataset_name]] <- names(labels)
1231+
# Select row 1 as default / fallback
1232+
selected_ix <- 1
1233+
# Define starting page index (base-0 index of the first item on page
1234+
# note: in many cases it's not the item itself
1235+
selected_page_ix <- 0
12051236

1206-
# calculate number of missing values
1207-
missings <- vapply(
1208-
df,
1209-
var_missings_info,
1210-
FUN.VALUE = character(1),
1211-
USE.NAMES = FALSE
1212-
)
1237+
# Retrieve current selected variable if any
1238+
isolated_variable <- shiny::isolate(plot_var$variable[[dataset_name]])
12131239

1214-
# get icons proper for the data types
1215-
icons <- stats::setNames(teal.slice:::variable_types(df), colnames(df))
1240+
if (!is.null(isolated_variable)) {
1241+
index <- which(columns_names[[dataset_name]] == isolated_variable)[1]
1242+
if (!is.null(index) && !is.na(index) && length(index) > 0) selected_ix <- index
1243+
}
12161244

1217-
join_keys <- get_join_keys(data)
1218-
if (!is.null(join_keys)) {
1219-
icons[intersect(join_keys$get(dataset_name)[[dataset_name]], colnames(df))] <- "primary_key"
1220-
}
1221-
icons <- variable_type_icons(icons)
1222-
1223-
# generate sparklines
1224-
sparklines_html <- vapply(
1225-
df,
1226-
create_sparklines,
1227-
FUN.VALUE = character(1),
1228-
USE.NAMES = FALSE
1229-
)
1245+
# Retrieve the index of the first item of the current page
1246+
# it works with varying number of entries on the page (10, 25, ...)
1247+
table_id_sel <- paste0("variable_browser_", dataset_name, "_state")
1248+
dt_state <- shiny::isolate(input[[table_id_sel]])
1249+
if (selected_ix != 1 && !is.null(dt_state)) {
1250+
selected_page_ix <- floor(selected_ix / dt_state$length) * dt_state$length
1251+
}
12301252

1231-
data.frame(
1232-
Type = icons,
1233-
Variable = names(labels),
1234-
Label = labels,
1235-
Missings = missings,
1236-
Sparklines = sparklines_html,
1237-
stringsAsFactors = FALSE
1238-
)
1239-
}
1240-
},
1241-
escape = FALSE,
1242-
rownames = FALSE,
1243-
selection = list(mode = "single", target = "row", selected = 1),
1244-
options = list(
1245-
fnDrawCallback = htmlwidgets::JS("function() { HTMLWidgets.staticRender(); }"),
1246-
pageLength = input[[paste0(table_ui_id, "_rows")]]
1253+
DT::datatable(
1254+
df_output,
1255+
escape = FALSE,
1256+
rownames = FALSE,
1257+
selection = list(mode = "single", target = "row", selected = selected_ix),
1258+
options = list(
1259+
fnDrawCallback = htmlwidgets::JS("function() { HTMLWidgets.staticRender(); }"),
1260+
pageLength = input[[paste0(table_ui_id, "_rows")]],
1261+
displayStart = selected_page_ix
1262+
)
12471263
)
1248-
)
1264+
})
12491265
}
12501266

12511267
#' Creates observers updating the currently selected column

man/render_tab_table.Rd

Lines changed: 4 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)