Skip to content

Commit 52612e1

Browse files
Copilotyihui
andauthored
Strip CDN versions from notebooks and add colors to show different plot regions (#51)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: yihui <163582+yihui@users.noreply.github.com> Co-authored-by: Yihui Xie <xie@yihui.name>
1 parent 92b876b commit 52612e1

File tree

6 files changed

+69
-6
lines changed

6 files changed

+69
-6
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.26
3+
Version: 0.0.28
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

R/render.R

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,10 @@ build_config = function(chart) {
218218

219219
# Theme: merge global option with per-chart theme
220220
theme = modifyList(as.list(getOption('gglite.theme')), as.list(chart$theme))
221+
# For dark themes, auto-set the view background so facet subplots get a dark
222+
# background (G2 uses transparent by default, making axis/grid hard to see).
223+
if (isTRUE(theme$type %in% c('dark', 'classicDark')))
224+
theme = modifyList(list(view = list(viewFill = '#141414')), theme)
221225
if (length(theme)) config$theme = theme
222226

223227
# Faceting wraps the spec as a facet view
@@ -293,7 +297,7 @@ chart_html = function(chart, id = NULL, width = NULL, height = NULL) {
293297
dark = isTRUE(chart$theme$type %in% c('dark', 'classicDark'))
294298
w = if (!is.null(width)) paste0('width:', width, 'px;') else ''
295299
h = if (!is.null(height)) paste0('height:', height, 'px;') else ''
296-
bg = if (dark) 'background-color:#141414;' else ''
300+
bg = if (dark) 'background-color:#141414;'
297301

298302
if (!is.null(threshold)) {
299303
# Ensure container has min-height so IntersectionObserver can trigger

examples/canvas.Rmd

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ pushing axis tick labels inward. Each argument accepts a scalar (all sides) or
2727
`c(top, right, bottom, left)` with `NA` to skip individual sides.
2828

2929
```{r}
30-
p |> canvas(padding = c(0, 150, NA, 100), margin = 10, inset = c(10, 0, 20, -20))
30+
p |>
31+
canvas(margin = 10, padding = c(10, 150, NA, 100), inset = c(10, 0, 20, -20)) |>
32+
theme_light(view = list(viewFill = '#fff3bf', plotFill = '#ffc9c9', mainFill = '#a5d8ff'))
3133
```
3234

3335
## Renderer

examples/themes.Rmd

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,24 @@ Themes control the overall visual appearance of the chart. Use helpers like
1111
`theme_classic()`, `theme_dark()`, `theme_light()`, `theme_classic_dark()`,
1212
and `theme_academy()` to set a built-in theme.
1313

14+
G2 provides five built-in themes in two pairs plus one standalone:
15+
16+
- **`classic` vs `light`**: both use a light background, but differ only in
17+
their default color palette for categorical data. `light` uses the AntV Light
18+
palette (e.g. `#1783FF`, `#00C9C9`, …), while `classic` (the default) uses
19+
G2's `category10` palette (e.g. `#5B8FF9`, `#5AD8A6`, …). When there is only
20+
a single data series, the two themes look identical because only one color is
21+
used.
22+
23+
- **`dark` vs `classicDark`**: the same relationship as above but on a dark
24+
background (`#141414`). `dark` uses the AntV Light palette colors on a dark
25+
canvas; `classicDark` uses the `category10` palette colors on a dark canvas.
26+
The only visible difference is the multi-series color palette.
27+
28+
- **`academy`**: a distinct style with custom fonts, color ramps, and decorative
29+
grid filters; it is not related to the classic/light or dark/classicDark
30+
pairs.
31+
1432
## Classic Theme (default)
1533

1634
```{r}

tests/normalize-notebook.py

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,26 @@
11
"""Normalize and copy an executed Jupyter notebook.
22
33
Strips execution metadata (execution counts, timestamps) that change between
4-
runs and copies the normalized notebook to the target path. Used by CI to
5-
produce a clean diff when deciding whether to open a PR.
4+
runs and copies the normalized notebook to the target path. Also strips version
5+
numbers from CDN resource URLs so that version bumps in upstream packages do
6+
not trigger new PRs to update the .ipynb output.
67
78
Usage: python tests/normalize-notebook.py <source.ipynb> <target.ipynb>
89
"""
9-
import json, sys
10+
import json, re, sys
11+
12+
13+
def strip_cdn_versions(s: str) -> str:
14+
"""Remove version specifiers (e.g. @5, @v0.14.34) from CDN URLs in src/href attributes."""
15+
return re.sub(r'((src|href)="https://[^"]*?)/@v?\d+(?:\.\d+)*', r'\1', s)
16+
17+
18+
def normalize_value(v):
19+
if isinstance(v, str):
20+
return strip_cdn_versions(v)
21+
if isinstance(v, list):
22+
return [normalize_value(x) for x in v]
23+
return v
1024

1125

1226
def normalize(nb: dict) -> None:
@@ -15,6 +29,13 @@ def normalize(nb: dict) -> None:
1529
cell.get('metadata', {}).pop('execution', None)
1630
for out in cell.get('outputs', []):
1731
out.pop('execution_count', None)
32+
for key in ('text', 'data'):
33+
if key in out:
34+
val = out[key]
35+
if isinstance(val, list):
36+
out[key] = [normalize_value(x) for x in val]
37+
elif isinstance(val, dict):
38+
out[key] = {k: normalize_value(v) for k, v in val.items()}
1839

1940

2041
if __name__ == '__main__':

tests/testit/test-theme.R

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,21 @@ assert('theme_classic_dark() sets classicDark theme', {
1919
chart = g2() |> mark_point() |> theme_classic_dark()
2020
(chart$theme$type %==% 'classicDark')
2121
})
22+
23+
assert('dark theme auto-sets viewFill in build_config', {
24+
chart = g2(mtcars, hp ~ mpg) |> theme_dark()
25+
config = build_config(chart)
26+
(config$theme$view$viewFill %==% '#141414')
27+
})
28+
29+
assert('classicDark theme auto-sets viewFill in build_config', {
30+
chart = g2(mtcars, hp ~ mpg) |> theme_classic_dark()
31+
config = build_config(chart)
32+
(config$theme$view$viewFill %==% '#141414')
33+
})
34+
35+
assert('light theme does not set viewFill', {
36+
chart = g2(mtcars, hp ~ mpg) |> theme_light()
37+
config = build_config(chart)
38+
(is.null(config$theme$view))
39+
})

0 commit comments

Comments
 (0)