Skip to content

Commit 8a8ac17

Browse files
Copilotyihui-bot
andauthored
Add Shiny examples for render_shiny()
Agent-Logs-Url: https://github.com/yihui/gglite/sessions/761adebb-cd4a-4204-9b05-27bd8cf72e48 Co-authored-by: yihui-bot <264330240+yihui-bot@users.noreply.github.com>
1 parent d60857b commit 8a8ac17

File tree

5 files changed

+198
-2
lines changed

5 files changed

+198
-2
lines changed

DESCRIPTION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Package: gglite
22
Title: Lightweight Data Visualization via the Grammar of Graphics
3-
Version: 0.0.2
3+
Version: 0.0.3
44
Authors@R: person("Yihui", "Xie", role = c("aut", "cre"), email = "xie@yihui.name",
55
comment = c(ORCID = "0000-0003-0645-5666"))
66
Description: A lightweight R interface to the AntV G2 JavaScript visualization

NEWS.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# gglite 0.1
22

3+
- Added Shiny examples in `examples/shiny.Rmd`.
4+
- Added a `\dontrun{}` example to `render_shiny()` showing minimal Shiny app setup.
5+
36
A lightweight R interface to the
47
[AntV G2](https://g2.antv.antgroup.com/) JavaScript visualization library with
58
a ggplot2-style API. Create interactive charts using the Grammar of Graphics

R/render.R

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,9 +177,35 @@ record_print.g2 = function(x, ...) {
177177

178178
#' Render a Chart in Shiny
179179
#'
180+
#' Render a `g2` chart in a Shiny app by sending the chart spec to a container
181+
#' element via a custom message. The UI must load the G2 CDN scripts and the
182+
#' gglite message handler; the container `<div>` must have a non-zero height.
183+
#' Call `render_shiny()` inside `observe()` or `observeEvent()` to re-render
184+
#' the chart reactively.
185+
#'
180186
#' @param chart A `g2` object.
181187
#' @param session The Shiny session object.
182188
#' @param output_id The container element ID on the client side.
189+
#' @examples
190+
#' \dontrun{
191+
#' library(shiny)
192+
#' ui = fluidPage(
193+
#' tags$head(
194+
#' tags$script(src = 'https://unpkg.com/@antv/g2@5/dist/g2.min.js'),
195+
#' tags$script(
196+
#' src = 'https://cdn.jsdelivr.net/npm/@xiee/utils/js/g2-column.min.js'
197+
#' ),
198+
#' includeScript(system.file('www/g2-handler.js', package = 'gglite'))
199+
#' ),
200+
#' div(id = 'chart1', style = 'height:480px')
201+
#' )
202+
#' server = function(input, output, session) {
203+
#' render_shiny(
204+
#' g2(mtcars, x = 'mpg', y = 'hp') |> mark_point(), session, 'chart1'
205+
#' )
206+
#' }
207+
#' shinyApp(ui, server)
208+
#' }
183209
#' @export
184210
render_shiny = function(chart, session, output_id) {
185211
spec = build_config(chart)

examples/shiny.Rmd

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
---
2+
title: Shiny
3+
---
4+
5+
gglite charts can be embedded in [Shiny](https://shiny.posit.co/) applications
6+
using `render_shiny()`. Unlike `htmlwidgets`-based packages, gglite uses
7+
Shiny's custom message passing to send chart specs to the browser, where the G2
8+
library renders them.
9+
10+
## Setup
11+
12+
Every Shiny app using gglite needs three script tags in the `<head>` of the UI:
13+
14+
1. The G2 JavaScript library from a CDN.
15+
2. The gglite column-major data helper.
16+
3. The gglite Shiny message handler (`g2-handler.js`), bundled with the package.
17+
18+
```r
19+
tags$head(
20+
tags$script(src = 'https://unpkg.com/@antv/g2@5/dist/g2.min.js'),
21+
tags$script(
22+
src = 'https://cdn.jsdelivr.net/npm/@xiee/utils/js/g2-column.min.js'
23+
),
24+
includeScript(system.file('www/g2-handler.js', package = 'gglite'))
25+
)
26+
```
27+
28+
The container `<div>` must have an explicit height (G2 charts will not appear
29+
in a zero-height container) and an `id` that matches the `output_id` argument
30+
you pass to `render_shiny()`:
31+
32+
```r
33+
div(id = 'my-chart', style = 'height:480px')
34+
```
35+
36+
## Basic Example
37+
38+
The simplest app renders a static chart when the session starts. Call
39+
`render_shiny()` directly in the server function:
40+
41+
```r
42+
library(shiny)
43+
library(gglite)
44+
45+
ui = fluidPage(
46+
tags$head(
47+
tags$script(src = 'https://unpkg.com/@antv/g2@5/dist/g2.min.js'),
48+
tags$script(
49+
src = 'https://cdn.jsdelivr.net/npm/@xiee/utils/js/g2-column.min.js'
50+
),
51+
includeScript(system.file('www/g2-handler.js', package = 'gglite'))
52+
),
53+
div(id = 'chart1', style = 'height:480px')
54+
)
55+
56+
server = function(input, output, session) {
57+
render_shiny(
58+
g2(mtcars, x = 'mpg', y = 'hp') |> mark_point(),
59+
session, 'chart1'
60+
)
61+
}
62+
63+
shinyApp(ui, server)
64+
```
65+
66+
## Reactive Example
67+
68+
Wrap `render_shiny()` in `observeEvent()` (or `observe()`) to re-render the
69+
chart whenever an input changes. Pass `ignoreNULL = FALSE` so the chart also
70+
renders on startup. The following app lets the user pick the y-axis variable
71+
from a dropdown:
72+
73+
```r
74+
library(shiny)
75+
library(gglite)
76+
77+
ui = fluidPage(
78+
tags$head(
79+
tags$script(src = 'https://unpkg.com/@antv/g2@5/dist/g2.min.js'),
80+
tags$script(
81+
src = 'https://cdn.jsdelivr.net/npm/@xiee/utils/js/g2-column.min.js'
82+
),
83+
includeScript(system.file('www/g2-handler.js', package = 'gglite'))
84+
),
85+
selectInput('yvar', 'Y variable', choices = c('hp', 'wt', 'qsec', 'drat')),
86+
div(id = 'chart1', style = 'height:480px')
87+
)
88+
89+
server = function(input, output, session) {
90+
observeEvent(input$yvar, {
91+
render_shiny(
92+
g2(mtcars, x = 'mpg', y = input$yvar) |>
93+
mark_point() |>
94+
title_of(input$yvar),
95+
session, 'chart1'
96+
)
97+
}, ignoreNULL = FALSE)
98+
}
99+
100+
shinyApp(ui, server)
101+
```
102+
103+
Each time the user picks a different variable, `render_shiny()` sends the
104+
updated spec to the browser and G2 re-renders the chart in place.
105+
106+
## Multiple Charts
107+
108+
You can render several charts independently by giving each container a distinct
109+
`id` and calling `render_shiny()` once per chart:
110+
111+
```r
112+
library(shiny)
113+
library(gglite)
114+
115+
ui = fluidPage(
116+
tags$head(
117+
tags$script(src = 'https://unpkg.com/@antv/g2@5/dist/g2.min.js'),
118+
tags$script(
119+
src = 'https://cdn.jsdelivr.net/npm/@xiee/utils/js/g2-column.min.js'
120+
),
121+
includeScript(system.file('www/g2-handler.js', package = 'gglite'))
122+
),
123+
fluidRow(
124+
column(6, div(id = 'scatter', style = 'height:400px')),
125+
column(6, div(id = 'bars', style = 'height:400px'))
126+
)
127+
)
128+
129+
server = function(input, output, session) {
130+
render_shiny(
131+
g2(mtcars, x = 'mpg', y = 'hp') |> mark_point(),
132+
session, 'scatter'
133+
)
134+
freq = as.data.frame(table(cyl = mtcars$cyl))
135+
render_shiny(
136+
g2(freq, x = 'cyl', y = 'Freq') |> mark_interval(),
137+
session, 'bars'
138+
)
139+
}
140+
141+
shinyApp(ui, server)
142+
```

man/render_shiny.Rd

Lines changed: 26 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)