---
title: "Quick Start with VizModules"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Quick Start}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
    collapse = TRUE,
    comment = "#>",
    eval = FALSE
)
```

## See the modules

Start with the hosted gallery to explore what each module can do:
<https://j-andrews7-VizModules.share.connect.posit.cloud/>

You can also run the same gallery locally from this package. Each tab opens a module
on an example dataset with its main features switched on, and the **Figure Builder** tab
combines several modules into one multi-panel figure:

```{r run-gallery}
library(VizModules)
moduleGalleryApp()
```

Each module's own example app (e.g. `plotthis_BoxPlotApp()`) opens on the same example
as its gallery tab.

## Working with an AI coding agent

**VizModules** ships three [Agent Skills](https://agentskills.io) that hand an agent the
package's conventions up front, rather than having it grep the docs for them. Install them
into your project with:

```{r install-skills}
VizModules::use_vizmodules_skills(".")                      # .agents/skills/ (OpenAI Codex, GitHub Copilot)
VizModules::use_vizmodules_skills(".", client = "copilot")  # .github/skills/ (GitHub Copilot)
VizModules::use_vizmodules_skills(".", client = "claude")   # .claude/skills/ (Claude Code)
```

- **`vizmodules-app`** covers what this vignette does: wiring modules into an app,
  `defaults`, `hide.inputs`/`hide.tabs`, the Stats tab, `createModuleApp()`, the data filter
  table, the figure builder, and source-data export. It carries a generated inventory of
  every module's column-mapping keys, colour key, and tab names, which is otherwise the
  most expensive thing for an agent to look up.
- **`vizmodules-custom-module`** covers building a wrapper module on top of a base module;
  see `vignette("custom-modules", package = "VizModules")`.
- **`vizmodules-new-module`** covers authoring a module inside this package; see
  `vignette("adding-a-new-module", package = "VizModules")`.

Restart your agent session after installing so the new directory is picked up. The README
has a plain-text prompt for tools that cannot read local skill files.

## Drop a module into your app

All modules follow the same pattern: `*InputsUI()` for controls, `*OutputUI()` for the plot, and `*Server()` for the logic.
Here is a minimal scatter plot example using the `dittoViz_scatterPlot` module:

```{r scatter-example}
library(VizModules)

# The same defaults go to the controls and the server, so Reset returns to them.
cars_defaults <- list(x.by = "wt", y.by = "mpg", color.by = "cyl")

ui <- fluidPage(
    sidebarLayout(
        sidebarPanel(
            dittoViz_scatterPlotInputsUI("cars", mtcars, defaults = cars_defaults)
        ),
        mainPanel(dittoViz_scatterPlotOutputUI("cars"))
    )
)

server <- function(input, output, session) {
    dittoViz_scatterPlotServer("cars", data = reactive(mtcars), defaults = cars_defaults)
}

shinyApp(ui, server)
```


## Set defaults and hide controls

- **Defaults**: Pass a named list to the `defaults` argument of `*InputsUI()` to pre-fill inputs, and the same list to the module's `*Server()` so its Reset button returns to them. Names are the module's input IDs, which mostly match the underlying plot function's arguments (e.g., `defaults = list(color.by = "cyl", size = 3)` for the scatter plot).
- **Reactive defaults**: An entry may be a `reactive()` instead of a fixed value, so an input follows your app's state (e.g. `defaults = list(color.by = reactive(input$colour_col))`). See `vignette("defaults-and-hiding", package = "VizModules")`.
- **Hide inputs**: Use `hide.inputs` in the server call to remove controls while still initializing their values. This is useful when your app sets certain parameters itself or wants to hide control of various elements while still passing their initial values.
- **Hide tabs**: Use `hide.tabs` to remove whole groups of controls (e.g., `"Plotly"` or `"Legend"` in `scatterPlot`).

```{r hide-controls}
server <- function(input, output, session) {
    dittoViz_scatterPlotServer(
        "cars",
        data = reactive(mtcars),
        hide.inputs = c("split.by", "shape.by"),
        hide.tabs = c("Plotly")
    )
}
```

Hidden inputs and tabs still feed their values into the plot, so the module stays fully configured while exposing only what your users need.

## App factory with `createModuleApp()`

To enable simple, consistent testing of any module, we provide an app factory function that returns a full 
standalone app with data import, a filterable data table, and dataset switching for any module - 
`createModuleApp()`:

```{r create-module-app}
library(VizModules)

app <- createModuleApp(
    inputs_ui_fn = plotthis_BarPlotInputsUI,
    output_ui_fn = plotthis_BarPlotOutputUI,
    server_fn    = plotthis_BarPlotServer,
    data_list    = list("cars" = example_mtcars),
    title        = "My Bar Plot"
)
if (interactive()) runApp(app)
```

All built-in `*App()` convenience functions (e.g. `plotthis_BarPlotApp()`, `linePlotApp()`)
are thin wrappers around `createModuleApp()` with sensible default data. You can also pass
custom wrapper module functions to `createModuleApp()` for rapid prototyping.

## Export Summary Data

We provide `collect_source_data()` to assemble a compact record of the
plotted data, stats, UI inputs, and the rendered plot, and `create_source_download_handler()`
to turn that record into a downloadable `.zip`. `collect_source_data()`
requires a reactive plotly plot; the output summary can be optionally enriched by
both a stats reactive and a UI inputs reactive. `create_source_download_handler()` also accepts
a named list of summaries (one per plot), which is how the Figure Builder bundles
every plot on its canvas into a single download.

The `.zip` also carries an SVG and a PNG of each plot. Those are photographed in
the browser, off the graph the user is looking at, so they match it exactly --
including everything applied after the figure was built, such as reference
lines, statistical brackets and dragged annotations. A module whose output is
not a plotly graph has nothing to photograph and supplies its own instead, by
putting a `vector_svg` and/or `raster_png` function of `(width, height, res)` on
its summary list; `draw_to_svg()` and `draw_to_png()` build one from any grid or
base drawing.

```{r data-summary}

if (interactive()) {
    library(shiny)
    library(plotly)

    ui <- fluidPage(
        plotlyOutput("plot"),
        downloadButton("download_summary", "Download Summary")
    )

    server <- function(input, output, session) {
        # A reactive plotly plot
        plot_reactive <- reactive({
            plot_ly(mtcars, x = ~wt, y = ~mpg, type = "scatter", mode = "markers")
        })

        # Optional: a reactive returning a stats data.frame
        stats_reactive <- reactive({
            data.frame(
                metric = c("mean_mpg", "sd_mpg"),
                value  = c(mean(mtcars$mpg), sd(mtcars$mpg))
            )
        })

        # Optional: capture all UI inputs as a named list
        AllInputs <- reactive({
            reactiveValuesToList(input)
        })

        output$plot <- renderPlotly(plot_reactive())

        # Assemble the summary, then wire up the download handler.
        plot_summary_reactive <- reactive({
            collect_source_data(
                plot_reactive   = plot_reactive,
                stats_reactive  = stats_reactive,
                inputs_reactive = AllInputs()
            )
        })

        output$download_summary <- create_source_download_handler(
            data_list     = plot_summary_reactive,
            filename_base = "my_plot_summary"
        )
    }

    shinyApp(ui, server)
}
```


## Which plot parameters are exposed?

Modules wrap plotting functions from **dittoViz**, **plotthis**, and native plotting functions. To see which arguments are available in a module:

1. Open the module input help page, e.g., `?dittoViz_scatterPlotInputsUI` or `?plotthis_AreaPlotInputsUI`. The **Details** section notes which arguments from the underlying plot function are wired through and any that are intentionally omitted.
2. Cross-reference the base plot documentation (`?dittoViz::scatterPlot`, `?plotthis::AreaPlot`, etc.). Input names in `defaults` line up with those function arguments when they are supported.

If an argument is listed as missing or non-functional in the module docs, it has been intentionally hidden because it does not round-trip well in the interactive Plotly output or is simply unnecessary due to plotly functionality.
