Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
14 changes: 4 additions & 10 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,6 @@ export(add_chart)
export(app_startup)
export(chart_template)
export(chartsNav)
export(chartsRenderModule)
export(chartsRenderModuleUI)
export(chartsRenderStatic)
export(chartsRenderStaticUI)
export(chartsRenderWidget)
export(chartsRenderWidgetUI)
export(chartsTab)
export(chartsTabUI)
export(create_new_safetyGraphics_app)
Expand All @@ -28,6 +22,9 @@ export(loadDataUI)
export(loadDomains)
export(loadDomainsUI)
export(makeChartConfig)
export(makeChartConfigFunctions)
export(makeChartExport)
export(makeChartParams)
export(makeChartSummary)
export(makeMapping)
export(mappingColumn)
Expand All @@ -38,8 +35,6 @@ export(mappingSelect)
export(mappingSelectUI)
export(mappingTab)
export(mappingTabUI)
export(reportsTab)
export(reportsTabUI)
export(safetyGraphicsApp)
export(safetyGraphicsInit)
export(safetyGraphicsServer)
Expand All @@ -66,8 +61,6 @@ importFrom(DT,renderDT)
importFrom(listviewer,jsonedit)
importFrom(listviewer,jsoneditOutput)
importFrom(listviewer,renderJsonedit)
importFrom(magrittr,extract)
importFrom(pharmaRTF,write_rtf)
importFrom(purrr,keep)
importFrom(purrr,map)
importFrom(purrr,map2)
Expand All @@ -93,5 +86,6 @@ importFrom(stringr,str_detect)
importFrom(stringr,str_split)
importFrom(stringr,str_to_title)
importFrom(stringr,str_to_upper)
importFrom(utils,hasName)
importFrom(utils,zip)
importFrom(yaml,write_yaml)
8 changes: 8 additions & 0 deletions R/app_startup.R
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ app_startup<-function(domainData=NULL, meta=NULL, charts=NULL, mapping=NULL, aut
}
}

# Drop charts where order is negative
orderDrops <- charts[purrr::map_lgl(charts, function(chart) chart$order < 0)]
if(length(orderDrops)>0){
message("Dropped ", length(orderDrops), " charts: ",paste(names(orderDrops),collapse=", "))
message("To display these charts, set the `order` parameter in the chart object or yaml file to a positive number.")
charts <- charts[purrr::map_lgl(charts, function(chart) chart$order >= 0)]
}

#Drop charts if data for required domain(s) is not found
chart_drops <- charts %>% purrr::keep(~(!all(.x$domain %in% names(domainData))))
if(length(chart_drops)>0){
Expand Down
2 changes: 2 additions & 0 deletions R/generateMappingList.R
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ generateMappingList <- function(settingsDF, domain=NULL, pull=FALSE){

if(is.null(domain)){
return(settingsList)
}else if(length(domain)>1){
return(settingsList)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fixes the bug noted in #595

}else{
return(settingsList[[domain]])
}
Expand Down
41 changes: 1 addition & 40 deletions R/makeChartConfig.R
Original file line number Diff line number Diff line change
Expand Up @@ -112,51 +112,12 @@ makeChartConfig <- function(dirs, packages="safetyCharts", packageLocation="conf
message("`env` paramter missing or not set to 'safetyGraphics'")
charts <- charts[purrr::map_lgl(charts, function(chart) chart$envValid)]
}

# Drop charts where order is negative
orderDrops <- charts[purrr::map_lgl(charts, function(chart) chart$order < 0)]
if(length(orderDrops)>0){
message("Dropped ", length(orderDrops), " charts: ",paste(names(orderDrops),collapse=", "))
message("To display these charts, set the `order` parameter in the chart object or yaml file to a positive number.")
charts <- charts[purrr::map_lgl(charts, function(chart) chart$order >= 0)]
}

# sort charts based on order
charts <- charts[order(purrr::map_dbl(charts, function(chart) chart$order))]
message("Loaded ", length(charts), " charts: ",paste(names(charts),collapse=", "))

# Bind workflow functions to chart object
all_functions <- as.character(utils::lsf.str(".GlobalEnv"))
message("Global Functions: ",all_functions)
charts <- lapply(charts,
function(chart){
if(utils::hasName(chart, "package")){
package_functions <- as.character(utils::lsf.str(paste0("package:",chart$package)))
all_functions<-c(all_functions,package_functions)
}

#search functions that include the charts name or the workflow function names
chart_function_names <- c()
for(query in c(chart$name, unlist(chart$workflow)) ){
matches<-all_functions[str_detect(query, all_functions)]
chart_function_names <- c(chart_function_names, matches)
}

chart$functions <- lapply(chart_function_names, match.fun)
names(chart$functions) <- chart_function_names

# check that functions exist for specified workflows
workflow_found <- sum(unlist(chart$workflow) %in% chart_function_names)
workflow_total <- length(unlist(chart$workflow)[names(unlist(chart$workflow))!="widget"])
message<-paste0(chart$name,": Found ", workflow_found, " of ",workflow_total, " workflow functions, and ", length(chart$functions)-workflow_found ," other functions.")
if(workflow_found == workflow_total){
message("+ ",message)
}else{
message("x ", message)
}

return(chart)
}
)
charts <- lapply(charts, makeChartConfigFunctions)
return(charts)
}
92 changes: 92 additions & 0 deletions R/makeChartConfigFunctions.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#' Make Chart Config Functions
#'
#' Binds needed functions to a chart object based on chart type.
#'
#' @param chart chart object like the one generated by makeChartConfig().
#'
#' @import purrr
#'
#' @return returns the chart object with a new functions object added.
#'
#' @export

makeChartConfigFunctions <- function(chart){
all_functions <- as.character(utils::lsf.str(".GlobalEnv"))

if(utils::hasName(chart, "package")){
package_functions <- as.character(utils::lsf.str(paste0("package:",chart$package)))
all_functions<-c(all_functions,package_functions)
}

#search functions that include the charts name or the workflow function names
chart_function_names <- c()
for(query in c(chart$name, unlist(chart$workflow)) ){
matches<-all_functions[str_detect(query, all_functions)]
chart_function_names <- c(chart_function_names, matches)
}

chart$functions <- lapply(chart_function_names, match.fun)
names(chart$functions) <- chart_function_names

# Define UI function unless one is provided
if(chart$type=="plot"){
chart$functions$ui<-plotOutput
chart$functions$server<-renderPlot
chart$functions$main<-chart$functions[[chart$workflow$main]]
}else if(chart$type=="html"){
chart$functions$ui<-htmlOutput
chart$functions$server<-renderText
chart$functions$main<-chart$functions[[chart$workflow$main]]
}else if(chart$type=="table"){
chart$functions$ui<-DT::dataTableOutput
chart$functions$server<-function(expr ){
DT::renderDataTable(
rownames = FALSE,
options = list(
pageLength = 20,
ordering = FALSE,
searching = FALSE
)
)
}
chart$functions$main<-chart$functions[[chart$workflow$main]]
#}
# }else if(chart$type=="rtf"){
# chart$functions$ui<-div(
# downloadButton(ns("downloadRTF"), "Download RTF"),
# DT::dataTableOutput(ns("chart-wrap"))
# )
}else if(chart$type=="htmlwidget"){
# Helper functions for html widget render
widgetOutput <- function(outputId, width = "100%", height = "400px") {
htmlwidgets::shinyWidgetOutput(outputId, chart$workflow$widget, width, height, package=chart$package)
}

renderWidget <- function(expr, env = parent.frame(), quoted = FALSE) {
if (!quoted) { expr <- substitute(expr) } # force quoted
htmlwidgets::shinyRenderWidget(expr, widgetOutput, env, quoted = TRUE)
}

chart$functions$ui<-widgetOutput
chart$functions$server<-renderWidget
chart$functions$main<-htmlwidgets::createWidget
chart$workflow$main <- "htmlwidgets::createWidget"

}else if (chart$type=="module"){
chart$functions$ui<-chart$functions[[chart$workflow$ui]]
chart$functions$server<-callModule
chart$functions$main <- chart$functions[[chart$workflow$server]]
}

# check that functions exist for specified workflows
workflow_found <- sum(unlist(chart$workflow) %in% chart_function_names)
workflow_total <- length(unlist(chart$workflow)[names(unlist(chart$workflow))!="widget"])
message<-paste0(chart$name,": Found ", workflow_found, " of ",workflow_total, " workflow functions, and ", length(chart$functions)-workflow_found ," other functions.")
if(workflow_found == workflow_total){
message("+ ",message)
}else{
message("x ", message)
}

return(chart)
}
112 changes: 112 additions & 0 deletions R/makeChartExport.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
#' Make Chart Config Functions
#'
#' Binds needed functions to a chart object based on chart type.
#'
#' @param chart chart object like the one generated by makeChartConfig().
#' @param mapping mapping object like the one generatedf by makeMapping().
#'
#' @import purrr
#' @importFrom utils hasName
#'
#' @return returns the chart object with an export script added.
#'
#' @export

makeChartExport <- function(chart, mapping){
# Load packages
packageScript<-c(
"library(yaml)",
paste0("library(",chart$package,")"),
"",
paste0("### Reproducible Code for ",chart$label, " (",chart$type,") ###"),
""
)

# TODO: src custom functions identified in workflow. Probably not a big deal for v2.0

# Load data
demodata <- list(
labs="safetyData::adam_adlbc",
aes="safetyData::adam_adae",
dm="safetyData::adam_adsl"
)
if(length(chart$domain)==1){
dataLoad <- paste0("data<-",demodata[[chart$domain]])
}else{

dataLoad<-c(
"data <- list(",
chart$domain %>% map_chr(~paste0(" ",.x, "=",demodata[[.x]])) %>% paste(collapse=",\n"),
")"
)
}

dataScript <- c(
"#Load Data",
"#NOTE: Correct data names should be updated by user",
dataLoad,
""
)

# Load mapping
mappingScript<-c(
"#Load mapping",
"#NOTE: mapping can also be saved as a .yaml and used for multiple charts.",
paste0('mapping_yaml<-"',as.yaml(mapping),'"'),
"mapping <- read_yaml(text=mapping_yaml)",
""
)

# make parameters
if(utils::hasName(chart$workflow, "init")){
paramScript <- c(
"# Create parameter list using custom initialization function",
paste0("params<-",chart$workflow$init,"(data,mapping)"),
""
)
}else{
paramScript<-c(
"# Create Parameter list",
"params<-list(data=data, settings=mapping)",
""
)
}

# format for widget (if needed)
if(chart$type =="htmlwidget"){
paramScript <- c(
paramScript,
"widgetParams <- list(",
paste0(" name='",chart$workflow$widget,"',"),
paste0(" package='",chart$package,"',"),
" sizingPolicy = htmlwidgets::sizingPolicy(viewer.suppress=TRUE, browser.external = TRUE),",
" x=list()",
")",
"widgetParams$x$data <- params$data",
"widgetParams$x$rSettings <- params$settings",
"widgetParams$x$settings <- jsonlite::toJSON(",
" params$settings,",
" auto_unbox = TRUE,",
' null = "null"',
")",
"params <- widgetParams",
""
)
}

# Initialize the chart
initScript<-c(
"# Run the chart",
paste0("do.call(",chart$workflow$main,",params)")
)

fullScript<- c(
packageScript,
dataScript,
mappingScript,
paramScript,
initScript
)

return(fullScript)
}
48 changes: 48 additions & 0 deletions R/makeChartParams.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#' @title Make Chart Parameters
#' @description Updates raw data and mapping for use with a specific chart
#'
#' @param data list of domain-level data
#' @param chart list containing chart specifications
#' @param mapping data frame with current mapping
#'
#' @export

makeChartParams <- function(data, chart, mapping){
settingsList <- safetyGraphics::generateMappingList(mapping, domain=chart$domain)

#subset data to specific domain (if specified)
if(length(chart$domain)>1){
domainData <- data
}else{
domainData<- data[[chart$domain]]
}
params <- list(data=domainData, settings=settingsList)

#customize initial the parameters if desired - otherwise pass through domain level data and mapping)
if(utils::hasName(chart,"functions")){
if(utils::hasName(chart$workflow,"init")){
message(chart$name, " has an init.")
params <- do.call(chart$functions[[chart$workflow$init]], params)
}
}

# format parameters for htmlwidget
if(chart$type == "htmlwidget"){
widgetParams <- list(
name=chart$workflow$widget,
package=chart$package,
sizingPolicy = htmlwidgets::sizingPolicy(viewer.suppress=TRUE, browser.external = TRUE),
x=list()
)
widgetParams$x$data <- params$data
widgetParams$x$rSettings <- params$settings
widgetParams$x$settings <- jsonlite::toJSON(
params$settings,
auto_unbox = TRUE,
null = "null",
)
params <- widgetParams
}

return(params)
}
2 changes: 1 addition & 1 deletion R/makeChartSummary.R
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ makeChartSummary<- function(chart, showLinks=TRUE, class="chart-header"){
target='_blank'
)
)
links<-div(tags$small("Links"), links, class="pull-right")
links<-div(tags$small("Links"), links)
}else{
links<-NULL
}
Expand Down
1 change: 1 addition & 0 deletions R/mod_chartsNav.R
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#'

chartsNav <- function(chart,ns){
print(chart$name)
appendTab(
inputId = "safetyGraphicsApp",
menuName = "Charts",
Expand Down
Loading