SkillAgentSearch skills...

Codehover

Hoverable HTML Table for Displaying Intermediary Code Results (e.g. Pipes)

Install / Use

/learn @arthurwelle/Codehover
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

codehover <img src="HexSticker/HexSticker.png" align="right" width="250" />

<!-- badges: start --> <!-- badges: end -->

Pipes are an excellent way to code. They make it easy to follow the code chain of transformations and their results.

The codehover aims to make it easy to create a HTML table with a simple hover effect (JavaScript/JQuery + CSS) that shows images just bellow the said table.

This way one could set up pseudo-lines of code (show as text) in the table and a series of images showing the intermediate results of the code with a hovering interaction.

The package use is educational, a fast way of showing code actions.

I have to say that I begin with the idea of the package without knowing about a similar package based on <a href= "https://github.com/yihui/xaringan">Xaringan</a>: <a href= "https://github.com/EvaMaeRey/flipbookr">flipbookr</a>. In fact, I guess it was in my subconscious all along, for I follow Gina Reynolds work on <a href= "https://twitter.com/EvaMaeRey">Twitter</a> for a long time. She made a wonderful job there, way more sophisticated than I even hope to implement here. codehover is aimed at a HTML page (through <a href="https://rmarkdown.rstudio.com/">RMarkdown</a>), with hover effect . By virtue of those simple differences I will keep the package online (until she implements the same functionality on flipbookr

  • granted that she already shows how to embed xaringan presentation into HTML(<a hred="https://evangelinereynolds.netlify.app/post/embedding-flipbook-mini-in-html-document/">here</a>)).

An example

To be fair this example is not well implemented yet. To make it side by side I manually change the CSS of the whole page.

See the <a href="https://arthurwelle.github.io/codehover/articles/codehover_map_example.html">HTML version here</a>.

Installation

You can install the experimental version of codehover from github:

install.packages("devtools")
devtools::install_github("arthurwelle/codehover")

After installation a new <a href="https://rstudio.github.io/rstudio-extensions/rmarkdown_templates.html">RMarkdown Template</a> shoud be available for you (File -> New File -> R Markdown -> From Template -> codehover). You should use this RMarkdown template in order to work with codehover because it loads the JavaScript/JQuery and the CSS necessary for its tasks.

Most of the times, as happnes with all new templates, after installation the template won’t show up in the menu right away. If this is the case, restart RStudio, it should come up then.

Every time you create a new codehover RMarkdown from template a folder will be created with the CSS and JavaScript files inside. They are needed to run the codehover properly, but once you have your final knitted file the CSS and the JavaScript will be attached to the HTML file, thus becoming self-contained.

library(ggplot2)
## Warning: package 'ggplot2' was built under R version 3.6.2

Workflow example

Let´s try to replicate the following graph (code and intermediate steps).

ggplot() +
  geom_point(data = cars,
             aes(x = speed, 
                 y = dist),
            color = 'red') +
  scale_y_continuous(limits = c(0,100)) +
  labs(title = 'A ggplot fot the rest of us',
       subtitle = 'Testing a way of explicit showing the R workflow') +
  theme_bw()
## Warning: Removed 1 rows containing missing values (geom_point).

<!-- -->

Save every step as an image.

g <- ggplot2::ggplot() +
  geom_point(data = cars,
             aes(x = speed, 
                 y = dist))

ggplot2::ggsave("./docs/1b.png", width = 4, height = 3) 

g <-  g + aes(color = "red")
ggplot2::ggsave("./docs/2b.png", width = 4, height = 3) 

g <-  g + scale_y_continuous(limits = c(0,100))
ggplot2::ggsave("./docs/3b.png", width = 4, height = 3) 

g <-  g + labs(title = "A ggplot fot the rest of us")
ggplot2::ggsave("./docs/4b.png", width = 4, height = 3) 

g <-  g + labs(subtitle = "Testing a way of explicit showing the R workflow")
ggplot2::ggsave("./docs/5b.png", width = 4, height = 3) 

g <-  g + theme_bw()
ggplot2::ggsave("./docs/6b.png", width = 4, height = 3) 

codehover has three functions that should be used together in a pipe-like style: ch_int(), ch_row(), and ch_out().

ch_int() initiates the HTML table, one can choose if the hover effect will be incremental or for a single row of the table. You can pass a custom CSS class for the whole table here as well.

After that you can use multiple ch_row calls to make as many rows as you like in the HTML table. For every line you should pass a text (the pseudo code you want to show) and an image. By default codehover uses <a href="https://yihui.org/knitr/">knitr</a> to encode the image file as a base64 string, with that your final HTML is self-contain in just one file (the images would be inside it). With multiple images this can increase file size considerable, so it´s optional to pass an url (with url = TRUE) if you dont want the behavior of embeding images. This way you can host your images anywhere.

Note that the code (the pseudo-code as text) use some <tabs> and   for indentation of the final text displayed. See more of that bellow.

Finally you should close the table with the function ch_out. Here you can indicate another image to be show before any hover interaction, as well as to pass another CSS class to the image holder to control its size and placement in the page.

With these three codehover functions you create an object (in fact just a text string) that htmltool::HMTL() function can inject in the HTML page.

library(magrittr)
## Warning: package 'magrittr' was built under R version 3.6.2
library(codehover)
result <- ch_int(type = "incremental") %>% 
          ch_row(text = 
                     "ggplot() + 
                      <br> <tab1> geom_point(data = cars, </tab1>
                      <br> <tab2> aes(x = speed, </tab2>
                      <br> <tab2> &nbsp; &nbsp; y = dist, </tab2>",
                   img ="./docs/1b.png") %>% 
          ch_row(text = "<tab2> color = 'red')) + </tab2>",
                   img ="./docs/2b.png") %>%   
          ch_row(text = "<tab1> scale_y_continuous(limits = c(0,100)) + </tab1>",
                   img ="./docs/3b.png") %>% 
          ch_row(text = "<tab1> labs(title = 'A ggplot fot the rest of us', </tab1>",
                   img ="./docs/4b.png") %>%   
          ch_row(text = "<tab2> subtitle = 'Testing a way of explicit showing the R workflow') + </tab2>",
                   img ="./docs/5b.png") %>% 
          ch_row(text = "<tab1>  theme_bw()</tab1> ",
                   img ="./docs/6b.png") %>%
          ch_out(img = "./docs/1b.png") 
 
ch_int 
## function(
##   type = "incremental", # options are "one_row" or "incremental"
##   css_class = "", # custom css
##   table_tag_add = "",
##   div_tag_add = "",
##   ...) {
## 
##   pipe_table_css <- "pipehover_incremental"
## 
##   if(type == "one_row"){pipe_table_css <- "pipehover_select_one_row"}
## 
##   .data <- paste0("<div ",div_tag_add,"> <table ",table_tag_add," class = '", pipe_table_css, " ", css_class, "'>")
## 
##   return(.data)
## }
## <bytecode: 0x7fc40767c1a0>
## <environment: namespace:codehover>
ch_row
## function(
##   .data = "" ,
##   text = "", # text inside the row
##   img = "", # image or url
##   url = FALSE, # set as TRUE to use a url link to an image hosted somewehere else
##   ...){
## 
##   if(url){
##     .data <- paste0(.data,  "<tr link='", img, "'><td>",text,"</td></tr> ")}else{
##       img_base64 <-  htmltools::img(src = knitr::image_uri(img))[["attribs"]][["src"]]
##       .data <- paste0(.data,  "<tr link='", img_base64, "'><td>",text,"</td></tr> ")
##     }
##   return(.data)
## }
## <bytecode: 0x7fc4075d68a0>
## <environment: namespace:codehover>
ch_out
## function(
##   .data = "" ,
##   img = "",
##   css_class = "",
##   url = FALSE,
##   img_tag_add = "",
##   div_tag_add = "",
##   ...){
## 
##   if(url){
##     .data <- paste0(.data,  "</table></div><div> <img id = 'img_holder' class='",css_class,"' src='", img, "'/></div>")}else{
##       img_base64 <-  htmltools::img(src = knitr::image_uri(img))[["attribs"]][["src"]]
##       .data <- paste0(.data,  "</table></div><div ",div_tag_add," > <img ",img_tag_add,"id = 'img_holder' class='",css_class,"' src='", img_base64,"'/></div>")
##     }
##   return(.data)
## }
## <bytecode: 0x7fc406dd0fc8>
## <environment: namespace:codehover>
result %>% cat()
## <div > <table  class = 'pipehover_incremental '><tr link='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABLAAAAOECAYAAACxbcj6AAAEGWlDQ1BrQ0dDb2xvclNwYWNlR2VuZXJpY1JHQgAAOI2NVV1oHFUUPrtzZyMkzlNsNIV0qD8NJQ2TVjShtLp/3d02bpZJNtoi6GT27s6Yyc44M7v9oU9FUHwx6psUxL+3gCAo9Q/bPrQvlQol2tQgKD60+INQ6Ium65k7M5lpurHeZe58853vnnvuuWfvBei5qliWkRQBFpquLRcy4nOHj4g9K5CEh6AXBqFXUR0rXalMAjZPC3e1W99Dwntf2dXd/p+tt0YdFSBxH2Kz5qgLiI8B8KdVy3YBevqRHz/qWh72Yui3MUDEL3q44WPXw3M+fo1pZuQs4tOIBVVTaoiXEI/MxfhGDPsxsNZfoE1q66ro5aJim3XdoLFw72H+n23BaIXzbcOnz5mfPoTvYVz7KzUl5+FRxEuqkp9G/Ajia219thzg25abkRE/BpDc3pqvphHvRFys2weqvp+krbWKIX7nhDbzLOItiM8358pTwdirqpPFnMF2xLc1WvLyOwTAibpbmvHHcvttU57y5+XqNZrLe3lE/Pq8eUj2fXKfOe3pfOjzhJYtB/yll5SDFcSDiH+hRkH25+L+sdxKEAMZahrlSX8ukqMOWy/jXW2m6M9LDBc31B9LFuv6gVKg/0Szi3KAr1kGq1GMjU/aLbnq6/lRxc4XfJ98hTargX++DbMJBSiYMIe9Ck1YAxFkKEAG3xbYaKmDDgYyFK0UGYpfoWYXG+fAPPI6tJnNwb7ClP7IyF+D+bjOtCpkhz6CFrIa/I6sFtNl8auFXGMTP34sNwI/JhkgEtmDz14ySfaRcTIBInmKPE32kxyyE2Tv+thKbEVePDfW/byMM1Kmm0XdObS7oGD/MypMXFPXrCwOtoYjyyn7BV29/MZfsVzpLDdRtuIZnbpXzvlf+ev8MvYr/Gqk4H/kV/G3csdazLuyTMPsbFhzd1UabQbjFvDRmcWJxR3zcfHkVw9GfpbJmeev9F08WW8uDkaslwX6avlWGU6NRKz0g/SHtCy9
View on GitHub
GitHub Stars70
CategoryDevelopment
Updated3mo ago
Forks5

Languages

R

Security Score

82/100

Audited on Dec 6, 2025

No findings