The goal of dockViewR is to provide a layout manager for Shiny apps and interactive R documents. It builds on top of dockview.
You can install the development version of dockViewR like so:
pak::pak("cynkra/dockViewR")
This is a basic example which shows you how to solve a common problem:
library(shiny)
library(bslib)
library(visNetwork)
nodes <- data.frame(id = 1:3)
edges <- data.frame(from = c(1, 2), to = c(1, 3))
ui <- page_fillable(
dock_viewOutput("dock")
)
server <- function(input, output, session) {
output$dock <- renderDock_view({
dock_view(
panels = list(
panel(
id = "1",
title = "Panel 1",
content = tagList(
sliderInput(
"obs",
"Number of observations:",
min = 0,
max = 1000,
value = 500
),
plotOutput("distPlot")
)
),
panel(
id = "2",
title = "Panel 2",
content = tagList(
visNetworkOutput("network")
),
position = list(
referencePanel = "1",
direction = "right"
),
minimumWidth = 500
),
panel(
id = "3",
title = "Panel 3",
content = tagList(
selectInput(
"variable",
"Variable:",
c("Cylinders" = "cyl", "Transmission" = "am", "Gears" = "gear")
),
tableOutput("data")
),
position = list(
referencePanel = "2",
direction = "below"
)
)
),
theme = "replit"
)
})
output$distPlot <- renderPlot({
req(input$obs)
hist(rnorm(input$obs))
})
output$network <- renderVisNetwork({
visNetwork(nodes, edges, width = "100%")
})
output$data <- renderTable(
{
mtcars[, c("mpg", input$variable), drop = FALSE]
},
rownames = TRUE
)
}
shinyApp(ui, server)
We welcome contributions! If you’d like to help improve {dockViewR}
,
feel free to submit issues, feature requests, or pull requests.
{dockViewR}
is an htmlwidget, an interactive widget for R, powered
by a JS library. To get a minimum starting kit:
- “Quick and Dirty” intro to JS for R devs: https://rsc.cynkra.com/js4Shiny/#/welcome.
- About htmlwidgets: https://www.htmlwidgets.org/develop_intro.html.
To contribute to this project, you’ll need npm
, node
, and the R
package {packer}
to compile the JavaScript code. Please follow the
slides attached to help you get started
pre-requisites.
When you are in the project, do the following:
pak::pak("packer")
# Restore JavaScript dependencies in package-lock.json (a bit like the renv.lock)
packer::npm_install()
The JS code uses ES6
modules,
meaning that you can define a module in a srcjs/component.js
script as
follows:
export const blabla = () => {
console.log("Blabla");
}
and use it in another script, let’s say ./otherscript.js
like so:
// ./otherscript.js
import { blabla } from './components.js'
Whenever you are done with changing the JS script, you have to rebuild it:
# Change the code and then rebundle
packer::bundle("development") # For developement mode
packer::bundle() # For production. Defaut!
You may as well bundle for dev
using packer::bundle_dev()
when in
developer mode and when ready for production use
packer::bundle_prod()
. You may also consider watch()
which watches
for changes in the srcjs
and rebuilds if necessary, equivalent to
npm run watch
.
- Whenever you run an app using
{dockViewR}
, like ininst/examples/demo
, open the viewer on a web browser window (preferably Chrome as it is used to illustrate the action in this step, as other browser devtools differ in term of layout). - Right-click on the widget and navigate to the
inspect
option on the drop-down menu. - At the top, where the tabs are displayed, navigate to the
Sources
tab. Open from the sidepaneldockviewer/srcjs/widgets/dockview.js
script. Once the
dockview.js
script is opened on the main panel. You can set a breakpoint on any line number of the script and reload the page.
This package is built on top of the amazing dockview JavaScript library.