Skip to content
Open
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
36 changes: 36 additions & 0 deletions R/api.R
Original file line number Diff line number Diff line change
Expand Up @@ -635,3 +635,39 @@ zoomOut <- function(id, percent = 0.5, animation = TRUE) {
method <- "zoomOut"
callJS()
}

#' Reset the timeline to its initial view
#'
#' Restores the timeline window to the state it was in when first rendered,
#' useful after zooming or panning.
#'
#' @param id Timeline id or a \code{timevis} object (the output from \code{timevis()})
#' @param animation Whether or not to animate the reset.
#' @examples
#' \dontrun{
#' timevis() %>%
#' resetTimevis()
#' }
#'
#' if (interactive()) {
#' library(shiny)
#' shinyApp(
#' ui = fluidPage(
#' timevisOutput("timeline"),
#' actionButton("btn", "Reset to initial view")
#' ),
#' server = function(input, output) {
#' output$timeline <- renderTimevis(
#' timevis()
#' )
#' observeEvent(input$btn, {
#' resetTimevis("timeline")
#' })
#' }
#' )
#' }
#' @export
resetTimevis <- function(id, animation = TRUE) {
method <- "resetTimevis"
callJS()
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
6 changes: 6 additions & 0 deletions R/timevis.R
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,12 @@ timevis_html <- function(id, style, class, ...){
class = "btn btn-default btn-lg zoom-out",
title = "Zoom out",
"-"
),
htmltools::tags$button(
type = "button",
class = "btn btn-default btn-lg zoom-reset",
title = "Reset to Initial View",
"↻"
)
)
)
Expand Down
59 changes: 56 additions & 3 deletions inst/htmlwidgets/timevis.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ HTMLWidgets.widget({
var ctSel = null;
var ctFil = null;
var allItems;
var originalWindow = null;

return {

Expand All @@ -38,6 +39,8 @@ HTMLWidgets.widget({
.onclick = function(ev) { that.zoomInTimevis(opts.zoomFactor); };
zoomMenu.getElementsByClassName("zoom-out")[0]
.onclick = function(ev) { that.zoomOutTimevis(opts.zoomFactor); };
zoomMenu.getElementsByClassName("zoom-reset")[0]
.onclick = function(ev) { that.resetTimevis(); };

// set listeners to events and pass data back to Shiny
if (HTMLWidgets.shinyMode) {
Expand Down Expand Up @@ -175,14 +178,53 @@ HTMLWidgets.widget({
// functions that the user wantd to run on the timeline before it was
// ready
var numApiCalls = opts['api'].length;

// Check if any API call will change the window
var hasWindowCall = false;
for (var i = 0; i < numApiCalls; i++) {
if (opts['api'][i].method === 'setWindow' ||
opts['api'][i].method === 'fitWindow' ||
opts['api'][i].method === 'centerTime' ||
opts['api'][i].method === 'centerItem') {
hasWindowCall = true;
break;
}
}
for (var i = 0; i < numApiCalls; i++) {
var call = opts['api'][i];
var method = call.method;
delete call['method'];
try {
that[method](call);
} catch(err) {}
} catch(err) {}
}

// Store the original window after fitting
if (originalWindow === null) {
if (hasWindowCall) {
// Skip the first rangechanged (from fit)
var fired = false;
timeline.on('rangechanged', function captureWindow() {
if (!fired) {
fired = true; // skip first fire (fit)
return;
}
originalWindow = {
start : timeline.getWindow().start,
end : timeline.getWindow().end
};
timeline.off('rangechanged', captureWindow); // remove listener
});
} else {
// No window API calls, just capture after fit
timeline.once('rangechanged', function() {
originalWindow = {
start : timeline.getWindow().start,
end : timeline.getWindow().end
};
});
}
}
Comment thread
Aravindpai152 marked this conversation as resolved.

// If crosstalk is enabled, respect its selection
allItems = opts.items;
Expand Down Expand Up @@ -239,6 +281,17 @@ HTMLWidgets.widget({
animation : animation
});
},
resetTimevis : function(animation) {
if (typeof animation === "undefined") {
animation = true;
}
if (originalWindow === null) return;
timeline.setWindow({
start : originalWindow.start,
end : originalWindow.end,
animation : animation
});
},
Comment thread
coderabbitai[bot] marked this conversation as resolved.

// export the timeline object for others to use if they want to
timeline : timeline,
Expand Down Expand Up @@ -306,7 +359,7 @@ HTMLWidgets.widget({
},
zoomOut : function(params) {
timeline.zoomOut(params.percent, { animation : params.animation });
},
}
};
}
});
Expand All @@ -317,7 +370,7 @@ if (HTMLWidgets.shinyMode) {
['addItem', 'addItems', 'removeItem', 'addCustomTime', 'removeCustomTime',
'fitWindow', 'centerTime', 'centerItem', 'setItems', 'setGroups',
'setOptions', 'setSelection', 'setWindow', 'setCustomTime', 'setCurrentTime',
'zoomIn', 'zoomOut'];
'zoomIn', 'zoomOut', 'resetTimevis'];

var addShinyHandler = function(fxn) {
return function() {
Expand Down