Skip to content

Commit

Permalink
render ggplot resizable
Browse files Browse the repository at this point in the history
  • Loading branch information
pvictor committed Mar 11, 2024
1 parent 9c929bb commit eb6fa27
Show file tree
Hide file tree
Showing 8 changed files with 124 additions and 15 deletions.
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ URL: https://dreamrs.github.io/esquisse/, https://github.com/dreamRs/esquisse
BugReports: https://github.com/dreamRs/esquisse/issues
License: GPL-3 | file LICENSE
Encoding: UTF-8
RoxygenNote: 7.2.3
RoxygenNote: 7.3.1
Roxygen: list(markdown = TRUE)
Imports:
bslib,
Expand Down
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ importFrom(shiny,NS)
importFrom(shiny,actionButton)
importFrom(shiny,actionLink)
importFrom(shiny,addResourcePath)
importFrom(shiny,bindEvent)
importFrom(shiny,browserViewer)
importFrom(shiny,callModule)
importFrom(shiny,checkboxInput)
Expand Down
52 changes: 47 additions & 5 deletions R/export.R
Original file line number Diff line number Diff line change
Expand Up @@ -194,8 +194,7 @@ save_ggplot_server <- function(id, plot_rv) {
#' @description Display a plot on the client and allow to download it.
#'
#' @param id Module ID.
#' @param width Width of the plot.
#' @param height Height of the plot.
#' @param width,height Width / Height of the plot, in the server it has to be a [shiny::reactive()] function returning a new width/height for the plot.
#' @param downloads Labels for export options, use `downloads_labels()` or `NULL` to disable export options.
#' @param ... Parameters passed to [shiny::plotOutput()] (`ggplot_output`) or [shiny::renderPlot()] (`render_ggplot`).
#'
Expand All @@ -212,12 +211,14 @@ save_ggplot_server <- function(id, plot_rv) {
ggplot_output <- function(id, width = "100%", height = "400px", downloads = downloads_labels(), ...) {
ns <- NS(id)
tags$div(
id = ns("ggplot-container"),
class = "ggplot-container",
style = css(
position = "relative",
width = validateCssUnit(width),
height = validateCssUnit(height)
),
html_dependency_moveable(),
if (!is.null(downloads)) {
e <- downloads[-1]
e <- e[-length(e)]
Expand Down Expand Up @@ -257,7 +258,11 @@ ggplot_output <- function(id, width = "100%", height = "400px", downloads = down
}
)
},
plotOutput(outputId = ns("plot"), width = width, height = height, ...)
plotOutput(outputId = ns("plot"), width = "100%", height = "100%", ...),
tags$div(
style = "display: none;",
textInput(inputId = ns("hidden"), label = NULL, value = genId())
)
)
}

Expand Down Expand Up @@ -292,24 +297,55 @@ downloads_labels <- function(label = ph("download-simple"),
#' is useful if you want to save an expression in a variable.
#' @param filename A string of the filename to export WITHOUT extension,
#' it will be added according to type of export.
#' @param resizable Can the chart size be adjusted by the user?
#'
#' @rdname ggplot-output
#'
#' @export
#'
#' @importFrom shiny exprToFunction moduleServer downloadHandler
#' reactiveValues renderPlot observeEvent showNotification is.reactive
#' reactiveValues renderPlot observeEvent showNotification is.reactive bindEvent
#' @importFrom shinyWidgets hideDropMenu
render_ggplot <- function(id,
expr,
...,
env = parent.frame(),
quoted = FALSE,
filename = "export-ggplot") {
filename = "export-ggplot",
resizable = FALSE,
width = reactive(NULL),
height = reactive(NULL)) {
gg_fun <- exprToFunction(expr, env, quoted)
moduleServer(
id = id,
module = function(input, output, session) {
ns <- session$ns
plot_width <- paste0("output_", ns("plot"), "_width")
plot_height <- paste0("output_", ns("plot"), "_height")

observeEvent(input$hidden, {
if (isTRUE(resizable))
activate_resizer(id = ns("ggplot-container"), modal = FALSE)
})

bindEvent(
observe({
if (
(is.reactive(width) && isTruthy(width())) &
(is.reactive(height) && isTruthy(height()))
) {
resize(
id = ns("ggplot-container"),
width = width(),
height = height(),
with_moveable = resizable
)
}
}),
width(),
height()
)

output$export_png <- download_plot_fun(gg_fun, "png", filename, session)
output$export_pdf <- download_plot_fun(gg_fun, "pdf", filename, session)
output$export_svg <- download_plot_fun(gg_fun, "svg", filename, session)
Expand Down Expand Up @@ -367,6 +403,12 @@ render_ggplot <- function(id,
)
})
save_ggplot_server("export", plot_rv = rv)
observe({
rv$plot_width <- session$clientData[[plot_width]]
})
observe({
rv$plot_height <- session$clientData[[plot_height]]
})
return(rv)
}
)
Expand Down
13 changes: 9 additions & 4 deletions R/utils-shiny.R
Original file line number Diff line number Diff line change
Expand Up @@ -172,9 +172,14 @@ activate_resizer <- function(id,
resize <- function(id,
width,
height,
with_moveable = TRUE,
session = shiny::getDefaultReactiveDomain()) {
session$sendCustomMessage(paste0("resize-", id), list(
width = width,
height = height
))
session$sendCustomMessage(
if (isTRUE(with_moveable)) paste0("resize-", id) else "esquisse-resize-plot",
list(
id = id,
width = width,
height = height
)
)
}
52 changes: 52 additions & 0 deletions examples/render-ggplot-resize.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@

library(shiny)
library(ggplot2)
library(esquisse)


ui <- fluidPage(
tags$h2("ggplot output"),
fluidRow(
column(
width = 3,
selectInput("var", "Variable:", names(economics)[-1]),
sliderInput("width", "Width:", 0, 1600, 800),
sliderInput("height", "Height:", 0, 1600, 400),
tags$p(
"Width: ", textOutput("plot_width"),
tags$br(),
"Height: ", textOutput("plot_height")
)
),
column(
width = 9,
ggplot_output("MYID", width = "600px", height = "400px")
)
)
)

server <- function(input, output, session) {

rv <- render_ggplot(
id = "MYID",
{
ggplot(economics) +
geom_line(aes(date, !!sym(input$var))) +
theme_minimal() +
labs(
title = "A cool chart made with ggplot2",
subtitle = "that you can export in various format"
)
},
resizable = TRUE,
width = reactive(input$width),
height = reactive(input$height)
)

output$plot_width <- renderText(rv$plot_width)
output$plot_height <- renderText(rv$plot_height)

}

if (interactive())
shinyApp(ui, server)
6 changes: 6 additions & 0 deletions inst/assets/moveable/resizer-handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,5 +93,11 @@ $(function() {
);
});
});
Shiny.addCustomMessageHandler("esquisse-resize-plot", function(obj) {
$("#" + obj.id).css({
"width": obj.width,
"height": obj.height
}).trigger("resize");
});
});

2 changes: 1 addition & 1 deletion man/esquisse.Rd

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

11 changes: 7 additions & 4 deletions man/ggplot-output.Rd

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

0 comments on commit eb6fa27

Please sign in to comment.