-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathREADME.Rmd
More file actions
147 lines (104 loc) · 7.4 KB
/
Copy pathREADME.Rmd
File metadata and controls
147 lines (104 loc) · 7.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
---
output: github_document
---
# codehover <img src="HexSticker/HexSticker.png" alt="codehover hex sticker" align="right" width="250" />
<!-- badges: start -->
[](https://github.com/arthurwelle/codehover/actions/workflows/R-CMD-check.yaml)
<!-- badges: end -->
codehover creates interactive HTML tables where each row is a step of code and hovering a row shows the corresponding image. It is an educational tool: a fast way of showing what each line of a ggplot (or any pipe-like code) actually does.

See a <a href="https://arthurwelle.github.io/codehover/articles/codehover_intro.html">live HTML version here</a>.
## Installation
You can install codehover from github:
``` r
install.packages("devtools")
devtools::install_github("arthurwelle/codehover")
```
## Quick start: automatic mode
Since version 1.0.0 you no longer need to save each image by hand, nor set up any CSS/JavaScript. Give `ch_hover()` your ggplot code and it does the rest: the code is split at every top-level `+`, each partial plot is rendered to an image, and the result is a self-contained HTML object that works in R Markdown, Quarto and the RStudio viewer.
``` r
library(ggplot2)
library(codehover)
ch_hover({
ggplot(mtcars, aes(x = wt, y = mpg)) +
geom_point(color = "red") +
scale_y_continuous(limits = c(0, 40)) +
labs(title = "A ggplot for the rest of us") +
theme_bw()
})
```
That single call replaces the whole manual workflow of v1 (saving six images with `ggsave()`, writing six `ch_row()` calls with hand-made pseudo-code, and wiring CSS and JavaScript through an R Markdown template).
### Options worth knowing
``` r
ch_hover({ ... },
type = "incremental", # or "one_row": highlight only the hovered row
layout = "auto", # image beside the code when there is room,
# below it otherwise. "row" forces side by side
# (image shrinks if needed); "column" forces
# the image below the code
fixed_scales = FALSE, # TRUE pins axes/legends from the final plot,
# so the image does not "jump" between steps
width = 7, height = 5, # image size in inches
dpi = 96,
path = NULL, # default: images embedded as base64 and deleted.
# give a folder ("assets/") to keep the PNGs on
# disk and reference them by path (smaller HTML)
alt = NULL, # alt text: one string per step, or one for all.
# default builds "Plot after step i of n: <code>"
caption = NULL, # caption shown under the image
initial = "last" # image shown before any interaction:
) # "last", "first" or a step number
```
By default each step shows the *true* output of its partial code, so axes and legends may change as layers are added — pedagogically honest. Use `fixed_scales = TRUE` for a visually stable reveal (this mechanism is borrowed from the excellent <a href="https://github.com/weverthonmachado/ggreveal">ggreveal</a> package by Weverthon Machado).
### Not only hover
Rows react to mouse hover, to **tap** on phones and tablets, and to the **keyboard**: Tab moves into the table, Arrow Up/Down walks the steps, Enter/Space activates one. Every image carries alternative text.
### Theming
The stylesheet is scoped under `.codehover` and exposes CSS custom properties, so you can restyle it without fighting specificity:
``` css
.codehover {
--codehover-highlight: #cde7ff; /* row highlight */
--codehover-font: monospace; /* code font */
--codehover-font-size: 0.9em;
--codehover-tab: 2em; /* width of one indent level */
}
```
A dark-scheme default is applied automatically through `prefers-color-scheme`.
### Keeping the source document clean
In R Markdown or Quarto you may prefer to write the plot in a normal chunk and reference it by label, so your document shows clean code:
````
```{r myplot, eval=FALSE}
ggplot(mtcars, aes(x = wt, y = mpg)) +
geom_point() +
geom_smooth(method = "lm")
```
`r knitr::inline_expr("ch_hover_chunk('myplot')")`
````
## Manual mode (low-level API)
The original building blocks are still exported, and they remain the way to go when your steps are *not* a single ggplot `+` chain: data-wrangling pipelines, maps built from several objects, any sequence of images with any pseudo-code.
You build the table by piping three functions — `ch_int()` starts it, `ch_row()` adds one row linked to one image, `ch_out()` closes it:
``` r
library(magrittr)
result <- ch_int(type = "incremental") %>%
ch_row(text = "ggplot() + <br> <tab1> geom_point(data = cars, aes(speed, dist)) </tab1>",
img = "./IMG/1.png") %>%
ch_row(text = "<tab1> scale_y_continuous(limits = c(0,100)) + </tab1>",
img = "./IMG/2.png") %>%
ch_row(text = "<tab1> theme_bw() </tab1>",
img = "./IMG/3.png") %>%
ch_out(img = "./IMG/3.png")
result
```
Since v1.0.0 `ch_out()` already returns a renderable object with the CSS and JavaScript attached — you no longer pass it through `htmltools::HTML()`, and no template is needed.
Inside `text` you can use `<br>` for line breaks, ` `/` `/` ` for spaces, and `<span class="ch-tab1">` ... `<span class="ch-tab16">` for indentation levels (the bare `<tab1>` ... `<tab16>` tags used by earlier versions are still styled, so old documents keep working). `ch_row(alt =)` sets the alternative text announced when that row is active. By default images are embedded into the HTML as base64 (self-contained single file); pass `url = TRUE` to reference images hosted elsewhere.
## An example with maps

See the <a href="https://arthurwelle.github.io/codehover/articles/codehover_map_example.html">HTML version here</a>.
## What changed in 1.0.0
* New: `ch_hover()` and `ch_hover_chunk()` — automatic splitting, rendering and assembling, now the main entry point.
* Output is self-contained: CSS and vanilla JavaScript travel with the HTML object (`htmltools` dependency). No more templates, YAML wiring, or jQuery/CDN.
* `ch_out()` returns the finished, renderable object directly (do not wrap it in `htmltools::HTML()` anymore).
* Rows now use the valid HTML5 `data-link` attribute (also fixes Quarto reveal.js usage); the fixed `id='img_holder'` is gone, so several tables can live on one page.
* Removed: the flipbookr-based functions (`chunk_code_hover()` etc.) and the flipbookr dependency. `ch_hover()` replaces them with no private-API usage and no `#<<` markers.
## Credits
I began this package without knowing about the similar (and more sophisticated) <a href="https://github.com/EvaMaeRey/flipbookr">flipbookr</a> by Gina Reynolds, based on <a href="https://github.com/yihui/xaringan">Xaringan</a> — it was probably in my subconscious all along. codehover v1's automatic mode was built on flipbookr internals; v2 has its own splitter but the idea remains hers. The `fixed_scales` mechanism comes from <a href="https://github.com/weverthonmachado/ggreveal">ggreveal</a> by Weverthon Machado.
The codehover hex sticker was made using the R package <a href="https://github.com/GuangchuangYu/hexSticker">hexSticker</a>.