To make it clearer here is a reproducible example:
Click here to download the test data ("TEMPWorkspace.RData").
# ADJUST PATH
load("TEMPWorkspace.RData")
# Load the necessary packages
library("rmarkdown")
library("shiny")
library("shinydashboard")
library("visNetwork")
library("foreach")
library("scales")
library("igraph") # https://datastorm-open.github.io/visNetwork/performance.html
#####
# User interface
ui <- dashboardPage(
dashboardHeader(title = "CTU Network"),
## Sidebar content
dashboardSidebar(
# tags$style(
# "text/css",
# "html,body,#map body {width:100%;height:150%}"),
sidebarUserPanel(name = "CTU Bern",image = "unibe_logo_mh.png"),
sidebarMenu(id = "tab",
# Look up available fonts: fontawesome:::fa_tbl
menuItem("Data Management", tabName = "datamanagement", icon = icon("database")),
menuItem("Statistics", tabName = "statistics", icon = icon("chart-area")),
menuItem("Clinical Study Management", tabName = "studymanagement", icon = icon("laptop-medical")),
menuItem("Monitoring", tabName = "monitoring", icon = icon("check")), # Would like to use the "magnifying-glass"
menuItem("Quality Management", tabName = "qualitymanagement", icon = icon("broom")),
radioButtons("projecttype", label = "Project", choices = c("IDs", "Names")),
selectInput("servicetype", label = "Service", choices = c("\a", "Basic", "Full", "Light")),
selectInput("dlfsupport", label = "DLF support", choices = c("\a", "Yes", "No")),
selectInput("cdms", label = "CDMS", choices = c("\a","REDCap", "secuTrial", "Webspirit")),
dateInput("prodfilter", label = "Productive date from", value = as.Date(NA)), # as.Date(NA) leads to a warning but has no consequences
dateInput("timebookfilter", label = "Time bookings from", value = as.Date(NA)),
radioButtons('format', 'Document format', c('HTML'), inline = TRUE), # , 'PDF'
downloadButton("DownloadReport", "Download Report", style = "margin: 5px 5px 40px 40px; "))),
## Body content
dashboardBody(
fluidRow(
visNetworkOutput("mynetworkid")
)
)
)
# Server
server <- function(input, output) { # Assemble inputs into outputs
# Update the database
DataUp <- reactive({
if (input$tab == 'datamanagement'){
FiltIdx <- mapply(grepl,"Data Management", Data$ProjectName, ignore.case=T) |
mapply(grepl,"Cloud", Data$ProjectName, ignore.case=T) |
mapply(grepl,"Study Website", Data$ProjectName, ignore.case=T) |
mapply(grepl,"DM", Data$ProjectName, ignore.case=T) |
grepl("DM", Data$ProjectName,fixed = T)
} else if (input$tab == 'statistics'){
FiltIdx <- mapply(grepl,"Statistics", Data$ProjectName, ignore.case=T) |
mapply(grepl,"Statistical Support", Data$ProjectName, ignore.case=T)
} else if (input$tab == 'studymanagement'){
FiltIdx <- mapply(grepl,"Clinical Investigation", Data$ProjectName, ignore.case=T) |
mapply(grepl,"Clinical Study Management", Data$ProjectName, ignore.case=T) |
mapply(grepl,"Project Coordination", Data$ProjectName, ignore.case=T)
} else if (input$tab == 'monitoring'){
FiltIdx <- mapply(grepl,"Monitoring", Data$ProjectName, ignore.case=T) |
mapply(grepl,"Document Development", Data$ProjectName, ignore.case=T) |
grepl("MON", Data$ProjectName,fixed = T)
} else if (input$tab == 'qualitymanagement'){
FiltIdx <- mapply(grepl,"Quality Management", Data$ProjectName, ignore.case=T) |
mapply(grepl,"QM Support", Data$ProjectName, ignore.case=T)
}
# Filter dataset
FiltIdx <- Data$PackageLvl %in% Data$UniqueCode[as.logical(FiltIdx)] |
Data$UniqueCode %in% Data$ProjectLvl[as.logical(FiltIdx)]
# Filter for service type
if (input$servicetype!="\a") {FiltIdx <- FiltIdx & as.logical(mapply(grepl,input$servicetype,Data$ServiceType, ignore.case=T))}
# Filter for clinical data management system (CDMS)
if (input$cdms!="\a") {FiltIdx <- FiltIdx & as.logical(mapply(grepl,input$cdms,Data$CDMS, ignore.case=T))}
# Filter for DLF support
if (input$dlfsupport!="\a") {FiltIdx <- FiltIdx & mapply(grepl,ifelse(input$dlfsupport=="Yes",T,F),Data$DLFSupport, ignore.case=T)}
# Apply filtering
DataUp <- Data[FiltIdx,]
# Filter for productive date from
if (length(input$prodfilter)>0) {
UniqueProj = split(seq_along(DataUp$ProjectIDs), DataUp$ProjectIDs)
DataUp <- DataUp[foreach(k=1:length(UniqueProj), .combine='c') %do%
rep(any(ifelse(DataUp[UniqueProj[[k]],"ProdDate"]-input$prodfilter>0,T,F),na.rm = T),length(UniqueProj[[k]])),]
}
# Filter for productive date from
if (length(input$timebookfilter)>0) {
Idx <- DataUp$BookedDate-input$timebookfilter>0
Idx[is.na(Idx)] <- TRUE
DataUp <- DataUp[Idx,]
}
# Computing different calculations based on filtering parameters
DataUp <- Calculations(DataUp)
# Function output
return(DataUp)
})
# Network plot
output$mynetworkid <- renderVisNetwork({
# Removing the lines corresponding to the project level (the aim is to separate for each division)
DataUp = DataUp()[DataUp()$Filt,]
# Build the color palette
# https://www.r-bloggers.com/2013/09/how-to-expand-color-palette-with-ggplot-and-rcolorbrewer/
ColCount = length(unique(DataUp$State))+1
getPalette = colorRampPalette(brewer.pal(9, "Set1")) # "Paired"
# Colors
Colors.df = data.frame(id = seq(1,length(unique(DataUp$State))+1),
label = c("Workers", unique(DataUp$State)),
color = getPalette(ColCount))
# Project type
Projtype = paste0("Project",input$projecttype) # Determined from radiobutton
UniqueProj = unique((DataUp[,Projtype])) # List of unique projects
# Edges
Edges <- data.frame(from = DataUp$Workers,
to = DataUp[,Projtype],
width = rescale(DataUp$TimeSpent, to=c(0,10)))
# Nodes
Nodes <- data.frame(id = c(unique(DataUp$Workers),unique(DataUp[,Projtype])),
label = c(unique(DataUp$Workers),unique(DataUp[,Projtype])),
group = c(rep("Workers",length(unique(DataUp$Workers))),(DataUp$State[match(unique(DataUp[,Projtype]), DataUp[,Projtype])])),
value = c(rep(10,length(unique(DataUp$Workers))),
rescale(foreach(k=1:length(UniqueProj), .combine='c') %do%
sum(DataUp$TimeSpent[which(DataUp[,Projtype] == UniqueProj[k])], na.rm = T), to=c(0,1000))),
shape = c(rep("square",length(unique(DataUp$Workers))),rep("dot",length(unique((DataUp[,Projtype]))))))
# Remove lines containing NA (under ID column)
Nodes = Nodes[!is.na(Nodes$id),]
Nodes$color <- lapply(Nodes$group, function(x) Colors.df$color[match(x, Colors.df$label)]) # Custom colors
# Build the network
visNetwork(Nodes, Edges, main = "CTU network", submain = "The size of each node corresponds to the amount of time booked") %>%
visIgraphLayout() %>%
visOptions(height = "1000", highlightNearest = T, nodesIdSelection = T, selectedBy= list(variable="group",multiple=T)) %>%
visPhysics(barnesHut = list(avoidOverlap = 0.1), stabilization = "onlyDynamicEdges") %>%
visLegend(useGroups = F,addNodes = Colors.df, position = "left", main = "State", ncol = 2, zoom = F) %>%
visNodes(shapeProperties = list(interpolation = F)) %>%
visEdges(smooth = F, color="darkgrey")
})
}
shinyApp(ui = ui, server = server)