Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add remove_timeline(). part of #1010 #1021

Merged
merged 2 commits into from
May 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ export(wb_remove_named_region)
export(wb_remove_row_heights)
export(wb_remove_slicer)
export(wb_remove_tables)
export(wb_remove_timeline)
export(wb_remove_worksheet)
export(wb_save)
export(wb_set_active_sheet)
Expand Down
14 changes: 13 additions & 1 deletion R/class-workbook-wrappers.R
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,7 @@ wb_add_pivot_table <- function(
#' * level: the granularity of the slicer (for timeline 0 = year, 1 = quarter, 2 = month)
#' * show_caption: logical if caption should be shown or not
#'
#' Removing slicers works on the spreadsheet level. Therefore all slicers are removed from a worksheet.
#' Removing works on the spreadsheet level. Therefore all slicers/timelines are removed from a worksheet. At the moment the drawing reference remains on the spreadsheet. Therefore spreadsheet software that does not handle slicers/timelines will still show the drawing.
#'
#' @param wb A Workbook object containing a worksheet.
#' @param x A `data.frame` that inherits the [`wb_data`][wb_data()] class.
Expand Down Expand Up @@ -636,6 +636,18 @@ wb_add_timeline <- function(

}

#' @rdname wb_add_slicer
#' @export
wb_remove_timeline <- function(
wb,
sheet = current_sheet()
) {
assert_workbook(wb)
wb$clone()$remove_timeline(
sheet = sheet
)
}

#' Add a formula to a cell range in a worksheet
#'
#' This function can be used to add a formula to a worksheet.
Expand Down
57 changes: 51 additions & 6 deletions R/class-workbook.R
Original file line number Diff line number Diff line change
Expand Up @@ -2113,19 +2113,21 @@ wbWorkbook <- R6::R6Class(

# without choose: filterType = unknown
timeline_cache <- read_xml(sprintf(
'<timelineCacheDefinition xmlns="http://schemas.microsoft.com/office/spreadsheetml/2010/11/main" xmlns:x15="http://schemas.microsoft.com/office/spreadsheetml/2010/11/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:xr10="http://schemas.microsoft.com/office/spreadsheetml/2016/revision10" mc:Ignorable="xr10" name="NativeTimeline_%s" xr10:uid="{7CE32DD1-8A45-FD42-8E6D-FD9376CAC325}" sourceName="%s">
'<timelineCacheDefinition xmlns="http://schemas.microsoft.com/office/spreadsheetml/2010/11/main" xmlns:x15="http://schemas.microsoft.com/office/spreadsheetml/2010/11/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:xr10="http://schemas.microsoft.com/office/spreadsheetml/2016/revision10" mc:Ignorable="xr10" name="NativeTimeline_%s" xr10:uid="%s" sourceName="%s">
<pivotTables>
<pivotTable tabId="%s" name="%s" />
</pivotTables>
<state minimalRefreshVersion="6" lastRefreshVersion="6" pivotCacheId="1" filterType="dateBetween">
<state minimalRefreshVersion="6" lastRefreshVersion="6" pivotCacheId="%s" filterType="dateBetween">
%s
%s
</state>
</timelineCacheDefinition>',
uni_name,
st_guid(),
timeline,
sheet,
pivot_table,
cid,
selection_xml,
bounds_xml
), pointer = FALSE)
Expand Down Expand Up @@ -2344,6 +2346,48 @@ wbWorkbook <- R6::R6Class(
invisible(self)
},

#' @description add pivot table
#' @return The `wbWorkbook` object
remove_timeline = function(sheet = current_sheet()) {
sheet <- private$get_sheet_index(sheet)

# get indices
timeline_id <- self$worksheets[[sheet]]$relships$timeline

# skip if nothing to do
if (identical(timeline_id, integer())) return(invisible(self))

cache_names <- unname(sapply(xml_attr(self$timelines[timeline_id], "timelines", "timeline"), "[", "cache"))
timeline_names <- unname(sapply(xml_attr(self$timelineCaches, "timelineCacheDefinition"), "[", "name"))
timeline_cache_id <- which(cache_names %in% timeline_names)

# strings to grep
timeline_xml <- sprintf("timelines/timeline%s.xml", timeline_id)
caches_xml <- sprintf("timelineCaches/timelineCache%s.xml", timeline_cache_id)

# empty timelines
self$timelines[timeline_id] <- ""
# empty timelineCache
self$timelineCaches[timeline_cache_id] <- ""

# remove timeline cache relship
self$worksheets[[sheet]]$relships$timeline <- integer()
# remove worksheet relationship
self$worksheets_rels[[sheet]] <- self$worksheets_rels[[sheet]][!grepl(timeline_xml, self$worksheets_rels[[sheet]])]
# remove "x15:timelineRefs"
is_ext_x15 <- grepl("xmlns:x15", self$worksheets[[sheet]]$extLst)
extLst <- xml_rm_child(self$worksheets[[sheet]]$extLst[is_ext_x15], xml_child = "x15:timelineRefs")
self$worksheets[[sheet]]$extLst[is_ext_x15] <- extLst

# clear workbook.xml.rels
self$workbook.xml.rels <- self$workbook.xml.rels[!grepl(paste0(caches_xml, collapse = "|"), self$workbook.xml.rels)]

# clear Content_Types
self$Content_Types <- self$Content_Types[!grepl(paste0(c(timeline_xml, caches_xml), collapse = "|"), self$Content_Types)]

invisible(self)
},

#' @description Add formula
#' @param x x
#' @param start_col startCol
Expand Down Expand Up @@ -2726,15 +2770,16 @@ wbWorkbook <- R6::R6Class(
timelinesDir <- dir_create(tmpDir, "xl", "timelines")
timelineCachesDir <- dir_create(tmpDir, "xl", "timelineCaches")

timeline <- self$timelines[self$timelines != ""]
for (i in seq_along(timeline)) {
timeline_id <- which(self$timelines != "")
for (i in timeline_id) {
write_file(
body = timeline[i],
body = self$timelines[i],
fl = file.path(timelinesDir, sprintf("timeline%s.xml", i))
)
}

for (i in seq_along(self$timelineCaches)) {
caches_id <- which(self$timelineCaches != "")
for (i in caches_id) {
write_file(
body = self$timelineCaches[[i]],
fl = file.path(timelineCachesDir, sprintf("timelineCache%s.xml", i))
Expand Down
2 changes: 2 additions & 0 deletions inst/WORDLIST
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ SubtotalRow
SuperA
SuperB
Textbox
TimelineStyleDark
TimelineStyleLight
TotalCell
TrafficLights
VARP
Expand Down
21 changes: 21 additions & 0 deletions man/wbWorkbook.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion man/wb_add_slicer.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions tests/testthat/test-class-workbook-wrappers.R
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,11 @@ test_that("wb_add_timeline() is a wrapper", {
expect_wrapper("add_timeline", wb = wb, params = list(x = df, timeline = "date", pivot_table = "pivot1"))
})

test_that("wb_remove_timeline() is a wrapper", {
wb <- wb_workbook()$add_worksheet()
expect_wrapper("remove_timeline", wb = wb)
})

test_that("wb_add_formula() is a wrapper", {
wb <- wb_workbook()$add_worksheet(1)
expect_wrapper("add_formula", wb = wb, params = list(sheet = 1, x = "=TODAY()"))
Expand Down
92 changes: 92 additions & 0 deletions tests/testthat/test-write.R
Original file line number Diff line number Diff line change
Expand Up @@ -692,6 +692,98 @@ test_that("removing slicers works", {

})

test_that("removing timelines works", {

### prepare data
df <- data.frame(
AirPassengers = c(AirPassengers),
time = seq(from = as.Date("1949-01-01"), to = as.Date("1960-12-01"), by = "month"),
letters = letters[1:4]
)

### create workbook
wb <- wb_workbook()$
add_worksheet("pivot")$
add_worksheet("pivot2")$
add_worksheet("data")$
add_data(x = df)

### get pivot table data source
df <- wb_data(wb, sheet = "data")

### first sheet
# create pivot table
wb$add_pivot_table(
df,
sheet = "pivot",
rows = "time",
cols = "letters",
data = "AirPassengers",
pivot_table = "airpassengers",
params = list(
compact = FALSE, outline = FALSE, compact_data = FALSE,
row_grand_totals = FALSE, col_grand_totals = FALSE)
)

# add slicer
wb$add_slicer(
df,
dims = "E1:I7",
sheet = "pivot",
slicer = "letters",
pivot_table = "airpassengers"
)

# add timeline
wb$add_timeline(
df,
dims = "E9:I14",
sheet = "pivot",
timeline = "time",
pivot_table = "airpassengers"
)

### second sheet
# create pivot table
wb$add_pivot_table(
df,
sheet = "pivot2",
rows = "time",
cols = "letters",
data = "AirPassengers",
pivot_table = "airpassengers2",
params = list(
compact = FALSE, outline = FALSE, compact_data = FALSE,
row_grand_totals = FALSE, col_grand_totals = FALSE)
)

# add slicer
wb$add_slicer(
df,
dims = "E1:I7",
sheet = "pivot2",
slicer = "letters",
pivot_table = "airpassengers2",
params = list(choose = c(letters = 'x %in% c("a", "b")'))
)

# add timeline
wb$add_timeline(
df,
dims = "E9:I14",
sheet = "pivot2",
timeline = "time",
pivot_table = "airpassengers2"
)

### remove slicer
wb$remove_timeline(sheet = "pivot")

temp <- temp_xlsx()
expect_silent(wb$save(temp)) # no warning, all files written as expected

})

test_that("writing na.strings = NULL works", {

# write na.strings = na_strings()
Expand Down
Loading