Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stream box values with updateBoxValue #304

Open
wants to merge 25 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
8dd2256
add simple message handler to update items
colearendt Dec 16, 2018
9a86795
add message handler to gruntfile
colearendt Dec 16, 2018
818480e
add simple streamValueBox implementation
colearendt Dec 16, 2018
0cbda48
update namespace
colearendt Dec 16, 2018
f31294d
add a js class to the value for easier lookup
colearendt Dec 16, 2018
e4e8b85
simplify lookup process
colearendt Dec 16, 2018
0bcb60d
add backwards compatible implementation for infoBox
colearendt Dec 16, 2018
7ed7719
update message handler to handle both value and info boxes
colearendt Dec 16, 2018
470e655
change class name
colearendt Dec 16, 2018
a00d4f4
add comments
colearendt Dec 16, 2018
ee1e70c
rename functions
colearendt Dec 16, 2018
4d4c6a7
update namespace
colearendt Dec 16, 2018
be031e9
update inst js files
colearendt Dec 16, 2018
a7b6b35
add note for error handling
colearendt Dec 16, 2018
13eee53
use safer class lookup
colearendt Dec 16, 2018
9870add
update docs with new version of roxygen
colearendt Dec 18, 2018
13ae7f8
update version of roxygen
colearendt Dec 18, 2018
3aa7750
add updateBoxValue documentation
colearendt Dec 18, 2018
63b4ac7
add updateBoxValue docs
colearendt Dec 18, 2018
c912aa9
update box documentation
colearendt Dec 18, 2018
3a6d538
update rendered js
colearendt Dec 18, 2018
de20d63
add direct rlang dependency
colearendt Dec 18, 2018
4e3108f
add rlang import
colearendt Dec 18, 2018
ecf8d89
add rlang dependency
colearendt Dec 18, 2018
136dc35
add example of remote box updates
colearendt Dec 18, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Imports:
utils,
shiny (>= 1.0.0),
htmltools (>= 0.2.6),
promises
promises,
rlang
BugReports: https://github.com/rstudio/shinydashboard
RoxygenNote: 6.0.1.9000
RoxygenNote: 6.1.1
2 changes: 2 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@ export(tabBox)
export(tabItem)
export(tabItems)
export(taskItem)
export(updateBoxValue)
export(updateTabItems)
export(valueBox)
export(valueBoxOutput)
import(htmltools)
import(promises)
importFrom(rlang,list2)
41 changes: 37 additions & 4 deletions R/boxes.R
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,21 @@
#' @param color A color for the box. Valid colors are listed in
#' \link{validColors}.
#' @param href An optional URL to link to.
#' @param id An optional id to uniquely identify the box
#'
#' @family boxes
#' @seealso \code{\link{box}} for usage examples.
#'
#' @export
valueBox <- function(value, subtitle, icon = NULL, color = "aqua", width = 4,
href = NULL)
href = NULL, id = NULL)
{
validateColor(color)
if (!is.null(icon)) tagAssert(icon, type = "i")

boxContent <- div(class = paste0("small-box bg-", color),
boxContent <- div(id = id, class = paste0("small-box bg-", color),
div(class = "inner",
h3(value),
h3(class = "value-box-value", value),
p(subtitle)
),
if (!is.null(icon)) div(class = "icon-large", icon)
Expand All @@ -39,6 +40,7 @@ valueBox <- function(value, subtitle, icon = NULL, color = "aqua", width = 4,
}



#' Create an info box for the main body of a dashboard.
#'
#' An info box displays a large icon on the left side, and a title, value
Expand All @@ -58,21 +60,23 @@ valueBox <- function(value, subtitle, icon = NULL, color = "aqua", width = 4,
#' content; the icon will use the same color with a slightly darkened
#' background.
#' @param href An optional URL to link to.
#' @param id An optional id to uniquely identify the box
#'
#' @family boxes
#' @seealso \code{\link{box}} for usage examples.
#'
#' @export
infoBox <- function(title, value = NULL, subtitle = NULL,
icon = shiny::icon("bar-chart"), color = "aqua", width = 4, href = NULL,
fill = FALSE) {
fill = FALSE, id = NULL) {

validateColor(color)
tagAssert(icon, type = "i")

colorClass <- paste0("bg-", color)

boxContent <- div(
id = id,
class = "info-box",
class = if (fill) colorClass,
span(
Expand Down Expand Up @@ -404,3 +408,32 @@ tabBox <- function(..., id = NULL, selected = NULL, title = NULL,

div(class = paste0("col-sm-", width), content)
}

#' Update the value of an infoBox or valueBox
#'
#' This function allows you to update the value of
#' an infoBox or valuebox without re-rendering the
#' entire box. It is useful for streaming data or
#' very regularly updating values
#'
#' @param session The session object that the infoBox
#' or valueBox belongs to
#' @param ... name=value pairs, where name is the id
#' (unique identifier) of an infoBox or valueBox, and
#' value is the value the box should display
#'
#' @family boxes
#' @seealso \code{\link{infoBox}}, \code{\link{valueBox}}
#'
#' @export
updateBoxValue <- function(session, ...) {
if (missing(session)) {
stop("Must provide a session, a name, and a value")
}

li <- rlang::list2(...)

session$sendCustomMessage("streamBox", li)

invisible()
}
1 change: 1 addition & 0 deletions R/shinydashboard-package.r
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
#'
#' @name shinydashboard
#' @import htmltools
#' @importFrom rlang list2
#' @docType package
NULL
23 changes: 23 additions & 0 deletions inst/shinydashboard.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion inst/shinydashboard.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions inst/shinydashboard.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion inst/shinydashboard.min.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion man/box.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions man/dashboardHeader.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions man/dashboardPage.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion man/dashboardSidebar.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion man/dropdownMenu.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions man/infoBox.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions man/notificationItem.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions man/sidebarMenu.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion man/tabBox.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 29 additions & 0 deletions man/updateBoxValue.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions man/valueBox.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions srcjs/message_handler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@


Shiny.addCustomMessageHandler('streamBox', function(data) {
$.each(data, function(key, val){
// get element
el = document.getElementById(key);

// TODO: Error handling... what if el does not exist?

// update value
if (el.classList.contains("small-box")) {
// for valueBox
el.getElementsByClassName("value-box-value")[0].innerText = val;
} else if (el.classList.contains("info-box")) {
// for infoBox
el.getElementsByClassName("info-box-number")[0].innerText = val;
}
});
});
37 changes: 37 additions & 0 deletions tests-manual/boxStream.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
library(shiny)
library(shinydashboard)

ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(),
dashboardBody(
valueBoxOutput("value_box"),
infoBoxOutput("info_box"),
infoBox("Title", 45, "Subtitle", icon = icon("bar-chart"), id = "testbox"),
valueBox(id = "someid", 45, "Subtitle", icon = icon("dashboard"))
),
title = "Test Streaming"
)

server <- function(input, output, session) {
value <- reactiveVal(45)
output$value_box <- renderValueBox({
valueBox(value(), "Subtitle", icon = icon("dashboard"))
})
output$info_box <- renderInfoBox({
infoBox("Title", value(), "Subtitle", icon = icon("bar-chart"))
})
observe({
invalidateLater(1000)
isolate(value(value() + 1))
print(paste("Updated value:", value()))
updateBoxValue(
session,
someid = value(),
testbox = value()
)
})
}

# Run the application
shinyApp(ui = ui, server = server)
1 change: 1 addition & 0 deletions tools/Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ module.exports = function(grunt) {
srcdirjs + 'input_binding_tabItem.js',
srcdirjs + 'input_binding_sidebarCollapsed.js',
srcdirjs + 'input_binding_sidebarmenuExpanded.js',
srcdirjs + 'message_handler.js',
srcdirjs + '_end.js'
],
dest: destdirjs + 'shinydashboard.js'
Expand Down