Descargas Directas de Datos y Gráficos

Empoderando al Usuario: Permitiendo la Exportación de Artefactos.

Más Allá del Reporte: Descargas Instantáneas

Los reportes parametrizados son perfectos para crear documentos formales. Sin embargo, a menudo los usuarios necesitan algo más simple y directo: la capacidad de descargar los datos con los que están trabajando o guardar una visualización específica como una imagen para usarla en una presentación.

Implementar funcionalidades de descarga directa es una de las formas más efectivas de aumentar el valor de tu aplicación Shiny. En esta lección, trabajaremos sobre la aplicación de exploración visual (`app_artefactos.R`) para añadirle estos botones.

Taller 1: Descargar Datos Filtrados a CSV

Añadiremos un botón que permita al usuario descargar un archivo `.csv` que contenga exactamente los datos que está viendo, respetando cualquier filtro que haya aplicado.

Paso 1: Añadir el Botón de Descarga a la UI

Usamos un downloadButton. Lo colocaremos en el `sidebarPanel` de la aplicación de artefactos (`app_artefactos.R`).

Acción: Añadir a `app_artefactos.R` (UI).

# En la UI de app_artefactos.R, dentro del sidebarPanel(...)
      
      # ... selectInputs existentes ...
      hr(),
      downloadButton(
        outputId = "descargar_datos",
        label = "Descargar Datos (CSV)",
        icon = icon("file-csv")
      )

Paso 2: Implementar la Lógica de Descarga en el Server

Usamos `downloadHandler`. La diferencia clave con los reportes es que en la función `content`, simplemente escribimos nuestro dataframe reactivo (`datos_filtrados()`) a un archivo usando `write.csv()`.

Acción: Añadir al Server de `app_artefactos.R`.

# En el Server de app_artefactos.R
  
  output$descargar_datos <- downloadHandler(
    filename = function() {
      paste0("datos-filtrados-icfes-", Sys.Date(), ".csv")
    },
    content = function(file) {
      # La clave: usamos el mismo conductor reactivo que alimenta
      # nuestros gráficos y tablas.
      write.csv(datos_filtrados(), file, row.names = FALSE)
    }
  )

La Magia de la Reactividad

Observa cómo estamos reutilizando el conductor reactivo datos_filtrados(). Esta es la belleza de una buena arquitectura. La misma lógica que filtra los datos para el gráfico de dispersión ahora también alimenta la función de descarga, garantizando consistencia total.

Taller 2: Guardar Gráfico como Imagen PNG

Ahora, permitiremos que el usuario guarde el gráfico de dispersión principal como un archivo de imagen de alta calidad.

Paso 1: Añadir el Botón en la UI

Colocaremos este botón directamente debajo del gráfico interactivo, en el `mainPanel`, para que esté contextualmente cerca de lo que se va a descargar.

Acción: Añadir a la UI de `app_artefactos.R`.

# En la UI de app_artefactos.R, dentro del mainPanel(...)
      
      plotlyOutput("scatter_plot"), # Gráfico existente
      hr(),
      downloadButton(
        outputId = "descargar_grafico",
        label = "Guardar Gráfico (PNG)",
        icon = icon("file-image")
      )

Paso 2: Implementar la Lógica de Guardado en el Server

Usamos la función `ggsave()` de `ggplot2`. Un punto clave es que necesitamos **re-crear el objeto del gráfico** dentro del `downloadHandler` para poder pasárselo a `ggsave()`. Esto nos da control total sobre la calidad de la imagen final (resolución, tamaño, etc.).

Acción: Añadir al Server de `app_artefactos.R`.

# En el Server de app_artefactos.R

  output$descargar_grafico <- downloadHandler(
    filename = function() {
      paste0("grafico-dispersion-", Sys.Date(), ".png")
    },
    content = function(file) {
      # Creamos el objeto ggplot que queremos guardar.
      # Es el mismo código que está en renderPlotly, pero sin ggplotly().
      plot_para_guardar <- ggplot(datos_filtrados(), aes_string(x = input$var_x, y = input$var_y)) +
        geom_point(aes(color = cole_naturaleza), alpha = 0.6) +
        labs(
          title = paste("Relación entre", input$var_x, "y", input$var_y),
          x = input$var_x, y = input$var_y
        ) +
        theme_minimal(base_size = 14)
        
      # Usamos ggsave para guardar el gráfico en el archivo
      ggsave(file, plot = plot_para_guardar, device = "png", width = 10, height = 6, dpi = 300)
    }
  )