Skip to content

Commit c0ec3e0

Browse files
author
Fred Wu
committed
added filterModel, and impoved row number column
1 parent af16566 commit c0ec3e0

2 files changed

Lines changed: 188 additions & 72 deletions

File tree

R/session/vsc.R

Lines changed: 73 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ get_column_def <- function(name, field, value) {
9797
)
9898
}
9999

100-
dataview_table <- function(data, start = 0, end = NULL, sortModel = NULL) {
100+
dataview_table <- function(data, start = 0, end = NULL, sortModel = NULL, filterModel = NULL) {
101101

102102
if (is.matrix(data)) {
103103
data <- as.data.frame.matrix(data)
@@ -109,8 +109,8 @@ dataview_table <- function(data, start = 0, end = NULL, sortModel = NULL) {
109109
data <- data.table::copy(data)
110110
data.table::setDT(data)
111111

112-
data[, "(row)" := .I]
113-
setcolorder(data, neworder = "(row)", before = 1)
112+
data[, `:=`("(row)" = numeric(), rowId = .I)]
113+
data.table::setcolorder(data, neworder = c("(row)", "rowId"), before = 1)
114114

115115
# number of rows & original column names
116116
.nrow <- nrow(data)
@@ -121,20 +121,69 @@ dataview_table <- function(data, start = 0, end = NULL, sortModel = NULL) {
121121
.colnames <- trimws(.colnames)
122122
}
123123

124-
# capture or generate rownames
125-
if (.row_names_info(data) > 0L) {
126-
rownames_ <- rownames(data)
127-
rownames(data) <- NULL
128-
} else {
129-
rownames_ <- seq_len(.nrow)
130-
}
131-
132124
fields <- sprintf("x%d", seq_along(.colnames))
133-
134-
# map x1→"(row)", x2→first real col, …
135125
field_map <- setNames(.colnames, fields)
136126

137-
# ── SORT data before slicing ──
127+
if (!is.null(filterModel) && length(filterModel) > 0) {
128+
129+
filter_strings <- lapply(names(filterModel), function(fld) {
130+
fd <- filterModel[[fld]]
131+
col_name <- field_map[[fld]]
132+
133+
if (!is.null(fd$type) && !is.null(fd$filter)) {
134+
op <- fd$type
135+
raw <- fd$filter
136+
137+
# quote or coerce the filter literal
138+
lit <- if (inherits(data[[col_name]], "Date")) {
139+
sprintf('as.Date("%s")', raw)
140+
} else if (is.numeric(data[[col_name]])) {
141+
as.numeric(raw)
142+
} else {
143+
sprintf('"%s"', gsub('"', '\\\\"', raw))
144+
}
145+
146+
# build the right comparison or string test
147+
expr <- switch(op,
148+
equals = sprintf('get("%s") == %s', col_name, lit),
149+
notEqual = sprintf('get("%s") != %s', col_name, lit),
150+
greaterThan = sprintf('get("%s") > %s', col_name, lit),
151+
greaterThanOrEqual = sprintf('get("%s") >= %s', col_name, lit),
152+
lessThan = sprintf('get("%s") < %s', col_name, lit),
153+
lessThanOrEqual = sprintf('get("%s") <= %s', col_name, lit),
154+
contains = sprintf('grepl(%s, get("%s"), fixed=TRUE)', lit, col_name),
155+
notContains = sprintf('!grepl(%s, get("%s"), fixed=TRUE)', lit, col_name),
156+
startsWith = sprintf('startsWith(get("%s"), %s)', col_name, lit),
157+
endsWith = sprintf('endsWith(get("%s"), %s)', col_name, lit),
158+
regexp = sprintf('grepl(%s, get("%s"))', lit, col_name),
159+
blank = sprintf('is.na(get("%s")) | get("%s") == ""', col_name, col_name),
160+
notBlank = sprintf('!is.na(get("%s")) & get("%s") != ""', col_name, col_name),
161+
inRange = {
162+
hi <- if (inherits(data[[col_name]], "Date")) {
163+
sprintf('as.Date("%s")', fd$filterTo)
164+
} else {
165+
as.numeric(fd$filterTo)
166+
}
167+
sprintf('get("%s") >= %s & get("%s") <= %s',
168+
col_name, lit, col_name, hi)
169+
},
170+
NULL
171+
)
172+
return(expr)
173+
}
174+
NULL
175+
})
176+
177+
filter_strings <- Filter(Negate(is.null), filter_strings)
178+
# combine with &&
179+
if (length(filter_strings) > 0) {
180+
combined <- paste(filter_strings, collapse = " & ")
181+
data <- data[eval(parse(text = combined))]
182+
}
183+
}
184+
185+
nFiltered <- nrow(data)
186+
138187
if (!is.null(sortModel) && length(sortModel) > 0) {
139188

140189
cols <- vapply(sortModel, function(s) field_map[[s$colId]], FUN.VALUE = "")
@@ -143,21 +192,19 @@ dataview_table <- function(data, start = 0, end = NULL, sortModel = NULL) {
143192
data.table::setorderv(data, cols, order = ords)
144193
}
145194

146-
if (is.null(end)) end <- .nrow
195+
if (is.null(end)) end <- nFiltered
147196
s <- as.integer(start) + 1
148-
e <- min(.nrow, as.integer(end))
197+
e <- min(nFiltered, as.integer(end))
149198

150-
if (s > .nrow || e < 1 || s > e) {
151-
rows <- data[0, , drop = FALSE]
152-
rownums <- integer(0)
199+
if (s > nFiltered || e < 1 || s > e) {
200+
rows <- data[0]
153201
} else {
154-
rows <- data[s:e, , drop = FALSE]
155-
rownums <- rownames_[s:e]
202+
rows <- data[s:e][, "(row)" := s:e]
156203
}
157204

158205
names(rows) <- fields
159206
class(rows) <- "data.frame"
160-
attr(rows, "row.names") <- .set_row_names(length(rownums))
207+
attr(rows, "row.names") <- .set_row_names(nrow(rows))
161208

162209
rows <- jsonlite::fromJSON(
163210
jsonlite::toJSON(rows, dataframe = "rows", na = "null", auto_unbox = TRUE)
@@ -171,7 +218,8 @@ dataview_table <- function(data, start = 0, end = NULL, sortModel = NULL) {
171218
list(
172219
columns = columns,
173220
rows = rows,
174-
totalRows = .nrow
221+
totalRows = nFiltered,
222+
totalUnfiltered = .nrow
175223
)
176224
}
177225

@@ -229,9 +277,9 @@ if (use_webserver) {
229277
return(result)
230278
}
231279
},
232-
dataview_fetch_rows = function(varname, start, end, sortModel, ...) {
280+
dataview_fetch_rows = function(varname, start, end, sortModel, filterModel, ...) {
233281
obj <- get(varname, envir = .GlobalEnv)
234-
out <- dataview_table(obj, start, end, sortModel)
282+
out <- dataview_table(obj, start, end, sortModel, filterModel)
235283
out$columns <- NULL
236284
return(out)
237285
}

0 commit comments

Comments
 (0)