Search code examples
rr-markdownflexdashboard

Combine storyboard and .no-mobile in flexdashboard?


In flexdashboard, it is easy to create a dashboard with a storyboard, see here:

https://rstudio.github.io/flexdashboard/articles/using.html#storyboards-1

Also, it is easy to have a specific output depending on mobile/not mobile;

https://pkgs.rstudio.com/flexdashboard/articles/using.html#mobile-css

But how can I combine the two? Whenever I do that, the mobile version is just shown either way, (with a blank page)

---
title: "Storyboard"
output: 
  flexdashboard::flex_dashboard:
    storyboard: true
---

### Chart 1

```{r}
print("non-mobile")
```   
 
### Chart 1 {.mobile}
    
```{r}
print("mobile")
```

Running the code just displays 2 tabs with the names Chart 1, Chart 1


Solution

  • You haven't respected the indented nature of additional specifications for the output in your YAML. It will not work with it.

    ---
    title: "Test"
    output: 
      flexdashboard::flex_dashboard:
        storyboard: true
    ---
    


    Update: This was not fun. However, it's pretty gratifying when I figure something like this out!

    Alright, so here's the thing, the mobile version is listening, but the storyboard-not-so-mobile is ignoring you.

    I did find comments in flexdashboard.js that mobility depends on whether or not the layout is set to fill. Storyboards are inherently more than one page, so they don't meet this requirement. So, I've made a workaround.

    I want to caveat and state that I can't possibly envision the many ways you might label your ### sections, nor how flexdashboard will translate the nearly infinite possible labels. This code should work with any combination of letters, numbers, and spaces. It might require adjustments for ### with special characters.

    For each of your sections (###) label it with either {.mobile} or {.no-mobile}. For availability in both, no label. (See my code to see what I mean. This is what you did.

    For each R chunk's output options, add class="mobile" or class="no-mobile". Again, no class is needed when used in both. Make sure that the capitalization is uniform in these labels. Don't add white space around the = in the chunk options.

    Along with the YAML in your questions:

    ### Let the charting begin {.no-mobile}
      
    ```{r showMePlease, class="no-mobile"}
    
    plot(x = 1:100, y = 100:1)
    
    ```   
    
    ### Chart 2 {.mobile}
    
    ```{r errrr, class="mobile"}
    
    plot(x = 1, y = 3)
    
    ```
    
    ### Chart 3 {.mobile}
    
    ```{r meow,class="mobile"}
    
    plot(x = 3, y = 3)
    
    ```
    
    ### Chart 4 {.no-mobile}
    
    ```{r pppplotttt, class="no-mobile"}
    
    plot(x = 10, y = 30)
    
    ```
    

    This next chunk can go anywhere in your RMD, but it needs to be there. If you try to run this chunk without knitting, it won't do anything. (Javascript only works when knit in RMD.)

    ```{r grrr,results="as-is",engine="js"}
    
    grrr = document.body; // there is no DOM! (sigh)
    setTimeout(function(){
      gimme = grrr.querySelectorAll('div.mobile');
      for(i = 0; i < gimme.length; i++) {
        // with each of the elements, collect the id labels
        // these labels match the storyboards
        gId = gimme[i].getAttribute('id');
        gId = gId.replace("-", " "); // all heading spaces get hyphens
                                     // need to prepare for matching
        // find the storyboards
        showMe = grrr.querySelectorAll('ul > li');
        for(j = 0; j < showMe.length; j++) {
          //if the story board matches a mobile plot, get rid of it
          if(showMe[j].textContent.toLowerCase() === gId) {
            showMe[j].style.display = "none";
          }
        }
      }
    }, 100); //delay!!
    ```
    

    Here are the storyboard and mobile versions.

    storyboard

    mobile