Please ignore the title of this post. It’s an exaggeration. In this post, I want to show an example that has the feel of a Shiny app, but it doesn’t really use Shiny or R as the backend when it runs. This example is from an answer of mine on a forum, and mainly intended for beginners who are interested in learning a little bit JavaScript, although I’m not a JavaScript expert. Below is the full R Markdown document:
---
title: "Change the number of bins of a histogram"
---
```{r, setup, echo=FALSE}
n_breaks = c(5, 10, 15, 20)
shiny::selectInput(
'n_breaks',
label = 'Number of bins',
choices = n_breaks,
selected = 5)
```
Draw all histograms and put them in a container with
the class `hist-all`.
```{r, class.chunk='hist-all'}
x = faithful$eruptions
for (i in n_breaks) {
hist(x, breaks = seq(min(x), max(x), length.out = i + 1),
main = paste('n = ', i))
}
```
But we hide all of those images initially with CSS.
```{css}
/* hide all images */
.hist-all img { display: none; }
/* but show the image with the class 'show' */
.hist-all .show { display: block; }
```
When the choice in the select input is changed, show
the histogram with the selected number of bins.
```{js}
(d => {
const s = d.getElementById('n_breaks'), // the select input
imgs = d.querySelectorAll('.hist-all img'); // all histograms
// add the class 'show' to the i-th image, where i is the
// selected number in the select input
function showImg() {
const i = s.selectedIndex;
imgs.forEach((el, k) => {
// k is the index of the image; i is the index of the choice
// in the select input; add the class 'show' if the two
// indices are equal
el.classList.toggle('show', k == i);
});
}
// show the initial image
showImg();
// show a different image when select input is changed
s.onchange = showImg;
})(document);
```
You can knit the document to HTML to play with the select input, or just visit
my demo. Personally I liked this example
because it’s a combination of my favorite technologies: R, CSS, and JavaScript.
R for drawing plots, CSS for appearance, and JavaScript for interaction. I have
tried to comment the code in detail, and I hope it’s not too hard to understand.
The key piece of JavaScript is el.classList.toggle()
.
This example could be useful when you want to present several plots one by one on a static HTML page that has no R or Shiny running behind it. But guess what? Someday you may be able to run real Shiny apps in your web browser without R or Shiny—WASM for the win!